2012-05-07 3 views
3

Возможно ли получить доступ к объявлениям дочерних пакетов из родительского пакета?Доступ к объявлениям дочерних пакетов

-- parent.ads 
package Parent is 
    procedure F(A : Child_Type); 
end Parent; 

-- parent-child.ads 
package Parent.Child is 
    type Child_Type is (A, B, C); 
end Parent.Child; 

вложенная версия работает отлично:

-- parent.ads 
package Parent is 
    package Child is 
     type Child_Type is (A, B, C); 
    end Child; 
    use Child; 

    procedure F(A : Child_Type); 
end Parent; 

А может быть, есть другой способ сделать это, так как я думаю, что это не возможно с помощью дочерних пакетов ...

+1

У меня был вопрос (http://stackoverflow.com/a/10515906/40851), отвечая на ваш другой вопрос .. используя пакеты для сиблинга, а не дочерние пакеты. –

ответ

1

В общем, нет ; второй пример работает, потому что спецификация Child известна, когда F объявлен в Parent. В свете вашего previous question на эту тему, возможно, вам нужен чистый способ разделения нескольких реализаций общей спецификации. В этом связанном Q&A обсуждаются два подхода: один с использованием наследования, а другой - с использованием библиотечного механизма во время компиляции.

+0

Итак, единственное решение, которое у меня есть, - сделать мой пакет общим с типами в качестве шаблонов шаблонов ... –

+0

Я отнесусь к более знающим участникам, но я не думаю, что есть достаточно информации, чтобы сказать, что это ваше решение _only_. Если наследование неуместно, дочерний орган может быть предоставлен во время компиляции. Мне пора идти. – trashgod

1

Я думаю, что вы ищете дочерний пакет private, это обычно ведет себя так же, как ваш вложенный пример, но вы не можете получить к нему доступ за пределами своего родительского тела.

Поэтому:

private package Parent.Child is 
    type Child_Type is (A,B,C); 
end Parent.Child; 

...

package Parent is 
    procedure F; 
end Parent; 

...

with Ada.Text_Io; 
with Parent.Child; 
package body Parent is 
    procedure F is 
    begin 
     for A in Parent.Child.Child_Type'Range loop 
     Ada.Text_Io.Put_Line (Parent.Child.Child_Type'Image (A)); 
     end loop; 
    end F; 
end Parent; 

ОК для компиляции, но помните, если вы с ребенком в родительском спецификации (как вы делаете с параметром до F), вы получите круговую зависимость, так как детям требуется, чтобы их родители существовали первыми!

Поэтому это действительно зависит от того, что вы хотите, чтобы быть открытыми для как родителя и ребенка, является ли фактическое решение вашей проблемы.

+0

Дело в том, что мне действительно нужно иметь пакет Child в отдельном файле, а то, что он содержит, должно быть прозрачным для использования в родительском пакете. Вот почему я ищу решение с дочерними пакетами: он может содержать декларации и может быть в отдельном файле; в то время как невозможно использовать 'отдельный' с объявлениями типов. Поэтому у меня по-прежнему возникает одна и та же проблема: мне нужно разделить объявления типов. –

+0

@JulioGuerra Нужно ли иметь объявления типа где-то в parent.child heirachy? Если нет, почему бы не поместить объявления типа в parent_types.ads и с этим файлом в parent.ads & parent.child.ads? – NWS

+0

Это невозможно: «' with' может появляться только в контексте контекста », который находится вне пакета. –

1

Julio, типы, объявленные в файле спецификации (mytypes.ads)

package Mytypes is 

    type Fruit is (Apple, Pear, Pineapple, Banana, Poison_Apple); 
    subtype Safe_Fruit is Fruit range Apple .. Banana; 

end Mytypes; 

... усыхания его в нескольких других:

with Mytypes; 
package Parent is 

    function Permission (F : in Mytypes.Fruit) return Boolean; 

end Parent; 

...

package body Parent is 

    function Permission (F : in Mytypes.Fruit) return Boolean is 
    begin 
     return F in Mytypes.Safe_Fruit; 
    end Permission; 

end Parent; 

...

package Parent.Child is 

    procedure Eat (F : in Mytypes.Fruit); 

end Parent.Child; 

...

with Ada.Text_Io; 
package body Parent.Child is 

    procedure Eat (F : in Mytypes.Fruit) is 
    begin 
     if Parent.Permission (F) then 
     Ada.Text_Io.Put_Line ("Eating " & Mytypes.Fruit'Image (F)); 
     else 
     Ada.Text_Io.Put_Line ("Forbidden to eat " & Mytypes.Fruit'Image (F)); 
     end if; 
    end Eat; 

end Parent.Child; 

...

with Mytypes; 
with Parent.Child; 

procedure Main is 

begin 

    for I in Mytypes.Fruit'Range loop 
     Parent.Child.Eat (I); 
    end loop; 

end Main; 

Он компилирует:

$ gnatmake main.adb 
gcc-4.4 -c parent-child.adb 
gnatbind -x main.ali 
gnatlink main.ali 

Это Работает:

$ ./main 
Eating APPLE 
Eating PEAR 
Eating PINEAPPLE 
Eating BANANA 
Forbidden to eat POISON_APPLE 

Является ли это то, что вы пробовали?

+0

Вам не нужно было писать полный пример :) Таким образом, вы помещаете тип в пакет, который является единицей компиляции. Да, это работает, но для меня есть семантическая/логическая проблема: этот тип принадлежит пакету Parent, и логика должна заключаться в том, чтобы они были в этом пакете, что пока невозможно (с разделением) :( –

Смежные вопросы