* Can't access record attribute in derived type
@ 2017-03-08 14:15 Mart van de Wege
2017-03-08 14:24 ` G.B.
` (2 more replies)
0 siblings, 3 replies; 13+ messages in thread
From: Mart van de Wege @ 2017-03-08 14:15 UTC (permalink / raw)
Hi,
I have the following definitions
private
type Creature is new Base_Creature with record
Attributes : Attribute_Array;
Gender : Possible_Gender := Unknown;
Current_Hit_Points : Integer;
Parents : Group_Of_Creatures.List;
-- An instance of Ada.Containers.Indefinite_Doubly_Linked_Lists
end record;
In child package #1 (Persons):
private
type Person is new Creature with record
[...]
and in child package #2 (Knights):
type Knight is new Person with record
[...]
I try to read the first element of the Parents attribute in knights.adb
like this:
function Father (K : in Knight) return Knight is
begin
return K.Parents.First_Element;
end Father;
And the compiler complains:
"no selector "Parents" for type "Knight" defined"
What am I missing here? The declarations are private, but shouldn't a
tagged type inherit the entire record of its parent type? That means
that it should have a Parents selector, shouldn't it?
Mart
--
"We will need a longer wall when the revolution comes."
--- AJS, quoting an uncertain source.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Can't access record attribute in derived type
2017-03-08 14:15 Can't access record attribute in derived type Mart van de Wege
@ 2017-03-08 14:24 ` G.B.
2017-03-08 15:06 ` Mart van de Wege
2017-03-08 20:08 ` Randy Brukardt
2017-03-08 21:03 ` Shark8
2 siblings, 1 reply; 13+ messages in thread
From: G.B. @ 2017-03-08 14:24 UTC (permalink / raw)
On 08/03/2017 15:15, Mart van de Wege wrote:
> The declarations are private, but shouldn't a
> tagged type inherit the entire record of its parent type? That means
> that it should have a Parents selector, shouldn't it?
Just to make sure, is this also a hierarchy of child
packages, like
P
Creature
P.C
Person
P.C.G
Knight
so that every derived type's definition has visibility
into the respective parent package's private part?
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Can't access record attribute in derived type
2017-03-08 14:24 ` G.B.
@ 2017-03-08 15:06 ` Mart van de Wege
2017-03-08 19:30 ` Niklas Holsti
0 siblings, 1 reply; 13+ messages in thread
From: Mart van de Wege @ 2017-03-08 15:06 UTC (permalink / raw)
"G.B." <bauhaus@notmyhomepage.invalid> writes:
> On 08/03/2017 15:15, Mart van de Wege wrote:
>> The declarations are private, but shouldn't a
>> tagged type inherit the entire record of its parent type? That means
>> that it should have a Parents selector, shouldn't it?
>
> Just to make sure, is this also a hierarchy of child
> packages, like
>
> P
> Creature
> P.C
> Person
> P.C.G
> Knight
>
> so that every derived type's definition has visibility
> into the respective parent package's private part?
>
Yep, it is.
Mart
--
"We will need a longer wall when the revolution comes."
--- AJS, quoting an uncertain source.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Can't access record attribute in derived type
2017-03-08 15:06 ` Mart van de Wege
@ 2017-03-08 19:30 ` Niklas Holsti
2017-03-08 21:05 ` Mart van de Wege
0 siblings, 1 reply; 13+ messages in thread
From: Niklas Holsti @ 2017-03-08 19:30 UTC (permalink / raw)
On 17-03-08 17:06 , Mart van de Wege wrote:
> "G.B." <bauhaus@notmyhomepage.invalid> writes:
>
>> On 08/03/2017 15:15, Mart van de Wege wrote:
>>> The declarations are private, but shouldn't a
>>> tagged type inherit the entire record of its parent type? That means
>>> that it should have a Parents selector, shouldn't it?
>>
>> Just to make sure, is this also a hierarchy of child
>> packages, like
>>
>> P
>> Creature
>> P.C
>> Person
>> P.C.G
>> Knight
>>
>> so that every derived type's definition has visibility
>> into the respective parent package's private part?
>>
> Yep, it is.
But you said that the problem appeared in a file called "knights.adb".
If that is the full name, and if you are using the GNAT file-name
convention, it is _not_ a child package of any other package. Did you
abbreviate the file name in your post?
A child package like Creatures.Persons.Knights would have a file-name of
the form "creatures-persons-knights.adb".
What are the actual and full names of all the relevant packages?
--
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
. @ .
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Can't access record attribute in derived type
2017-03-08 14:15 Can't access record attribute in derived type Mart van de Wege
2017-03-08 14:24 ` G.B.
@ 2017-03-08 20:08 ` Randy Brukardt
2017-03-08 21:06 ` Mart van de Wege
2017-03-08 21:12 ` Mart van de Wege
2017-03-08 21:03 ` Shark8
2 siblings, 2 replies; 13+ messages in thread
From: Randy Brukardt @ 2017-03-08 20:08 UTC (permalink / raw)
"Mart van de Wege" <mvdwege@gmail.com> wrote in message
news:86mvcv4zyu.fsf@gaheris.avalon.lan...
> Hi,
>
> I have the following definitions
>
> private
> type Creature is new Base_Creature with record
> Attributes : Attribute_Array;
> Gender : Possible_Gender := Unknown;
> Current_Hit_Points : Integer;
> Parents : Group_Of_Creatures.List;
> -- An instance of Ada.Containers.Indefinite_Doubly_Linked_Lists
> end record;
>
> In child package #1 (Persons):
>
> private
> type Person is new Creature with record
> [...]
> and in child package #2 (Knights):
> type Knight is new Person with record
> [...]
>
> I try to read the first element of the Parents attribute in knights.adb
> like this:
>
> function Father (K : in Knight) return Knight is
> begin
> return K.Parents.First_Element;
> end Father;
>
> And the compiler complains:
>
> "no selector "Parents" for type "Knight" defined"
>
> What am I missing here? The declarations are private, but shouldn't a
> tagged type inherit the entire record of its parent type? That means
> that it should have a Parents selector, shouldn't it?
I suspect we'll need to see a more complete example to definitively say what
the problem is.
But if I had to guess, I'd suggest that you've run afoul of the "sibling
inheritance problem". The rule for visibility for child components is that
*all* of components of the *all* of the ancestors have to be visible at the
point of declaration of the child type. If even one of the ancestors is not
visible (as happens when deriving from a type defined in a sibling child
package), then the components aren't visible, either.
Note that in such a case, if you have visiblity on some but not all of the
ancestors, you can type convert the object to make them visible. In your
example above:
return Creature(K).Parents.First_Element;
will work if you have some intermediate ancestor without visible components.
So, if the above works, you have a sibling inheritance problem, and your
choices are either to use conversions like the above, or move the types so
that all of the ancestors are visible.
Randy.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Can't access record attribute in derived type
2017-03-08 14:15 Can't access record attribute in derived type Mart van de Wege
2017-03-08 14:24 ` G.B.
2017-03-08 20:08 ` Randy Brukardt
@ 2017-03-08 21:03 ` Shark8
2017-03-08 21:16 ` Mart van de Wege
2 siblings, 1 reply; 13+ messages in thread
From: Shark8 @ 2017-03-08 21:03 UTC (permalink / raw)
On Wednesday, March 8, 2017 at 7:15:22 AM UTC-7, Mart van de Wege wrote:
> Hi,
>
> I have the following definitions
>
> private
> type Creature is new Base_Creature with record
> Attributes : Attribute_Array;
> Gender : Possible_Gender := Unknown;
> Current_Hit_Points : Integer;
> Parents : Group_Of_Creatures.List;
> -- An instance of Ada.Containers.Indefinite_Doubly_Linked_Lists
> end record;
>
> In child package #1 (Persons):
>
> private
> type Person is new Creature with record
> [...]
> and in child package #2 (Knights):
> type Knight is new Person with record
> [...]
>
> I try to read the first element of the Parents attribute in knights.adb
> like this:
>
> function Father (K : in Knight) return Knight is
> begin
> return K.Parents.First_Element;
> end Father;
One Problem is that K.Parents.First_Element *isn't* of type Knight -- It's of type Creature -- that is surely one problem.
Secondly, the construct
> type Creature is new Base_Creature with record
> Attributes : Attribute_Array;
> Gender : Possible_Gender := Unknown;
> Current_Hit_Points : Integer;
> Parents : Group_Of_Creatures.List;
> -- An instance of Ada.Containers.Indefinite_Doubly_Linked_Lists
> end record;
cannot exist, as you cannot instantiate the Container without completing the type which can't be complete without the instantiation of the Container (because of the Parents element).
I would recommend something like this:
Type Base_Creature is abstract tagged record
Attributes : Attribute_Array;
Gender : Possible_Gender := Unknown;
Current_Hit_Points : Integer;
end record;
--...
Package Creature_Grouping is new Ada.Containers.Indefinite_Doubly_Linked_Lists( Base_Creature'Class );
--...
Type Creature is new Base_Creature with record
Parents : Creature_Grouping.List;
end record;
--...
Type Person is new Creature with --[...]
Function Father( Input : Person ) return Creature'Class is
( Input.Parents.First_Element );
--...
Type Knight is new Person with --[...]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Can't access record attribute in derived type
2017-03-08 19:30 ` Niklas Holsti
@ 2017-03-08 21:05 ` Mart van de Wege
0 siblings, 0 replies; 13+ messages in thread
From: Mart van de Wege @ 2017-03-08 21:05 UTC (permalink / raw)
Niklas Holsti <niklas.holsti@tidorum.invalid> writes:
> On 17-03-08 17:06 , Mart van de Wege wrote:
>> "G.B." <bauhaus@notmyhomepage.invalid> writes:
>>
>>> On 08/03/2017 15:15, Mart van de Wege wrote:
>>>> The declarations are private, but shouldn't a
>>>> tagged type inherit the entire record of its parent type? That means
>>>> that it should have a Parents selector, shouldn't it?
>>>
>>> Just to make sure, is this also a hierarchy of child
>>> packages, like
>>>
>>> P
>>> Creature
>>> P.C
>>> Person
>>> P.C.G
>>> Knight
>>>
>>> so that every derived type's definition has visibility
>>> into the respective parent package's private part?
>>>
>> Yep, it is.
>
> But you said that the problem appeared in a file called
> "knights.adb". If that is the full name, and if you are using the GNAT
> file-name convention, it is _not_ a child package of any other
> package. Did you abbreviate the file name in your post?
>
> A child package like Creatures.Persons.Knights would have a file-name
> of the form "creatures-persons-knights.adb".
>
> What are the actual and full names of all the relevant packages?
Aaah. I think I see the problem. Yes, Knights is on the same level of
the hierarchy as Persons.
The full hierarchy is:
Pendragon
Pendragon.Persons
Pendragon.Knights
Knights withs Persons, but they are on the same level.
(And for the curious, this is a random character generator for the King
Arthur Pendragon roleplaying game. It works quite well for the 50% of
the rules I already covered, creating single characters, but I have
problems getting my design to work with families, aka containers within
the Persons/Knights objects containing other Persons/Knights).
Mart
--
"We will need a longer wall when the revolution comes."
--- AJS, quoting an uncertain source.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Can't access record attribute in derived type
2017-03-08 20:08 ` Randy Brukardt
@ 2017-03-08 21:06 ` Mart van de Wege
2017-03-08 21:12 ` Mart van de Wege
1 sibling, 0 replies; 13+ messages in thread
From: Mart van de Wege @ 2017-03-08 21:06 UTC (permalink / raw)
"Randy Brukardt" <randy@rrsoftware.com> writes:
> I suspect we'll need to see a more complete example to definitively say what
> the problem is.
>
> But if I had to guess, I'd suggest that you've run afoul of the "sibling
> inheritance problem". The rule for visibility for child components is that
> *all* of components of the *all* of the ancestors have to be visible at the
> point of declaration of the child type. If even one of the ancestors is not
> visible (as happens when deriving from a type defined in a sibling child
> package), then the components aren't visible, either.
>
> Note that in such a case, if you have visiblity on some but not all of the
> ancestors, you can type convert the object to make them visible. In your
> example above:
>
> return Creature(K).Parents.First_Element;
>
> will work if you have some intermediate ancestor without visible components.
> So, if the above works, you have a sibling inheritance problem, and your
> choices are either to use conversions like the above, or move the types so
> that all of the ancestors are visible.
>
> Randy.
>
>
>
--
"We will need a longer wall when the revolution comes."
--- AJS, quoting an uncertain source.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Can't access record attribute in derived type
2017-03-08 20:08 ` Randy Brukardt
2017-03-08 21:06 ` Mart van de Wege
@ 2017-03-08 21:12 ` Mart van de Wege
2017-03-08 21:25 ` Mart van de Wege
1 sibling, 1 reply; 13+ messages in thread
From: Mart van de Wege @ 2017-03-08 21:12 UTC (permalink / raw)
"Randy Brukardt" <randy@rrsoftware.com> writes:
> I suspect we'll need to see a more complete example to definitively say what
> the problem is.
>
The full code lives at https://github.com/mvdwege/pendragon
Note that some stuff is in incomplete branches, and I still have some
locally committed changes that are not in the github repo. The code that
was throwing errors among them.
> But if I had to guess, I'd suggest that you've run afoul of the "sibling
> inheritance problem". The rule for visibility for child components is that
> *all* of components of the *all* of the ancestors have to be visible at the
> point of declaration of the child type. If even one of the ancestors is not
> visible (as happens when deriving from a type defined in a sibling child
> package), then the components aren't visible, either.
>
It appears that that is it. While Knights is a descendant of Person, the
Knights package is indeed a sibling of Persons, not a child.
I failed to let my package design keep up with the actual design of the
objects.
The problem went away when I moved the Knights definition into the
Persons package. Now I know why.
(In fact, my original design had a wild growth of child packages which I
was in the process of pruning back as being excessively complex. Which
probably caused my confusion above).
> Note that in such a case, if you have visiblity on some but not all of the
> ancestors, you can type convert the object to make them visible. In your
> example above:
>
> return Creature(K).Parents.First_Element;
Yes, using conversions in my unit tests suppressed other errors I
couldn't get, and now I understand why those conversions were
necessary.
Mart
--
"We will need a longer wall when the revolution comes."
--- AJS, quoting an uncertain source.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Can't access record attribute in derived type
2017-03-08 21:03 ` Shark8
@ 2017-03-08 21:16 ` Mart van de Wege
0 siblings, 0 replies; 13+ messages in thread
From: Mart van de Wege @ 2017-03-08 21:16 UTC (permalink / raw)
Shark8 <onewingedshark@gmail.com> writes:
> On Wednesday, March 8, 2017 at 7:15:22 AM UTC-7, Mart van de Wege wrote:
>> Hi,
>>
>> I have the following definitions
>>
>> private
>> type Creature is new Base_Creature with record
>> Attributes : Attribute_Array;
>> Gender : Possible_Gender := Unknown;
>> Current_Hit_Points : Integer;
>> Parents : Group_Of_Creatures.List;
>> -- An instance of Ada.Containers.Indefinite_Doubly_Linked_Lists
>> end record;
>>
>> In child package #1 (Persons):
>>
>> private
>> type Person is new Creature with record
>> [...]
>> and in child package #2 (Knights):
>> type Knight is new Person with record
>> [...]
>>
>> I try to read the first element of the Parents attribute in knights.adb
>> like this:
>>
>> function Father (K : in Knight) return Knight is
>> begin
>> return K.Parents.First_Element;
>> end Father;
>
> One Problem is that K.Parents.First_Element *isn't* of type Knight --
> It's of type Creature -- that is surely one problem.
>
Yeah, that is solved by some explicit conversions. I am not happy with
that, but this is still the first phase of my attempt at implementing
families, and getting my head around the intricacies of OO in Ada.
> Secondly, the construct
>> type Creature is new Base_Creature with record
>> Attributes : Attribute_Array;
>> Gender : Possible_Gender := Unknown;
>> Current_Hit_Points : Integer;
>> Parents : Group_Of_Creatures.List;
>> -- An instance of Ada.Containers.Indefinite_Doubly_Linked_Lists
>> end record;
> cannot exist, as you cannot instantiate the Container without completing the type which can't be complete without the instantiation of the Container (because of the Parents element).
>
> I would recommend something like this:
>
> Type Base_Creature is abstract tagged record
> Attributes : Attribute_Array;
> Gender : Possible_Gender := Unknown;
> Current_Hit_Points : Integer;
> end record;
>
> --...
> Package Creature_Grouping is new Ada.Containers.Indefinite_Doubly_Linked_Lists( Base_Creature'Class );
> --...
That's more or less what I did. Creature is derived from abstract
Base_Creature, and Group_Of_Creatures is defined as new
Ada.Containers.Indefinite_Doubly_Linked_list (Element_Type =>
Base_Creature'Class).
Mart
--
"We will need a longer wall when the revolution comes."
--- AJS, quoting an uncertain source.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Can't access record attribute in derived type
2017-03-08 21:12 ` Mart van de Wege
@ 2017-03-08 21:25 ` Mart van de Wege
2017-03-08 21:50 ` Simon Wright
0 siblings, 1 reply; 13+ messages in thread
From: Mart van de Wege @ 2017-03-08 21:25 UTC (permalink / raw)
Mart van de Wege <mvdwege@gmail.com> writes:
> "Randy Brukardt" <randy@rrsoftware.com> writes:
>
>> I suspect we'll need to see a more complete example to definitively say what
>> the problem is.
>>
> The full code lives at https://github.com/mvdwege/pendragon
>
> Note that some stuff is in incomplete branches, and I still have some
> locally committed changes that are not in the github repo. The code that
> was throwing errors among them.
Screw that. Based on my reading of the answers, I am going to delete the
persons and family_and_relatives branches and sit down and do a decent
design first.
Mart
--
"We will need a longer wall when the revolution comes."
--- AJS, quoting an uncertain source.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Can't access record attribute in derived type
2017-03-08 21:25 ` Mart van de Wege
@ 2017-03-08 21:50 ` Simon Wright
2017-03-08 22:35 ` Mart van de Wege
0 siblings, 1 reply; 13+ messages in thread
From: Simon Wright @ 2017-03-08 21:50 UTC (permalink / raw)
Mart van de Wege <mvdwege@gmail.com> writes:
> Mart van de Wege <mvdwege@gmail.com> writes:
>
>> "Randy Brukardt" <randy@rrsoftware.com> writes:
>>
>>> I suspect we'll need to see a more complete example to definitively
>>> say what the problem is.
>>>
>> The full code lives at https://github.com/mvdwege/pendragon
>>
>> Note that some stuff is in incomplete branches, and I still have some
>> locally committed changes that are not in the github repo. The code
>> that was throwing errors among them.
>
> Screw that. Based on my reading of the answers, I am going to delete
> the persons and family_and_relatives branches and sit down and do a
> decent design first.
I suspect most of us have reached this stage in a project at some point
in our careers! You will feel better afterwards ...
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Can't access record attribute in derived type
2017-03-08 21:50 ` Simon Wright
@ 2017-03-08 22:35 ` Mart van de Wege
0 siblings, 0 replies; 13+ messages in thread
From: Mart van de Wege @ 2017-03-08 22:35 UTC (permalink / raw)
Simon Wright <simon@pushface.org> writes:
> Mart van de Wege <mvdwege@gmail.com> writes:
>
>> Mart van de Wege <mvdwege@gmail.com> writes:
>>
>>> "Randy Brukardt" <randy@rrsoftware.com> writes:
>>>
>>>> I suspect we'll need to see a more complete example to definitively
>>>> say what the problem is.
>>>>
>>> The full code lives at https://github.com/mvdwege/pendragon
>>>
>>> Note that some stuff is in incomplete branches, and I still have some
>>> locally committed changes that are not in the github repo. The code
>>> that was throwing errors among them.
>>
>> Screw that. Based on my reading of the answers, I am going to delete
>> the persons and family_and_relatives branches and sit down and do a
>> decent design first.
>
> I suspect most of us have reached this stage in a project at some point
> in our careers! You will feel better afterwards ...
I've been working on this off and on for almost a year now, and I have
reached that point several times ;)
And you're right, I've felt better every time I did that. In fact, just
after reading the comments I coded up an implementation that correctly
assigns a Father to a Person'Class object, stuffs it in the Parents
list, and reads it correctly. So the first steps of the redesign
work. Now I'm going to think on how to implement the entire family tree
according to the rules.
The nice thing about implementing RPG rulesets is that the ruleset
itself presents a decent first attempt at a spec ;)
Mart
--
"We will need a longer wall when the revolution comes."
--- AJS, quoting an uncertain source.
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2017-03-08 22:35 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-08 14:15 Can't access record attribute in derived type Mart van de Wege
2017-03-08 14:24 ` G.B.
2017-03-08 15:06 ` Mart van de Wege
2017-03-08 19:30 ` Niklas Holsti
2017-03-08 21:05 ` Mart van de Wege
2017-03-08 20:08 ` Randy Brukardt
2017-03-08 21:06 ` Mart van de Wege
2017-03-08 21:12 ` Mart van de Wege
2017-03-08 21:25 ` Mart van de Wege
2017-03-08 21:50 ` Simon Wright
2017-03-08 22:35 ` Mart van de Wege
2017-03-08 21:03 ` Shark8
2017-03-08 21:16 ` Mart van de Wege
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox