Rafael Garcia-Suarez asked: > Damian Conway <[EMAIL PROTECTED]> wrote: > >>There are in fact *two* types associated with any Perl variable > > How does it work regarding inheritance and polymorphism ? > E.g. consider > my @a is Set of Apple; > my @b is Basket of Fruit; > with Apple isa Fruit, and Basket is a Set. > > I assume I can use @a or @b where the expected type is: > > @a @b > Set ok ok > Set of Fruit ok ok > Set of Apple ok no(?) > Basket no ok > Basket of Fruit no ok > Basket of Apple no no(?)
All of these seem to make the same incorrect assumption: that the implementation type specifies what a variable evaluates to. It doesn't. The storage type does that. So, saying: my @a is Set of Apple; doesn't make C<@a> evaluate to an object of class C<Set of Apple>. Nor does it define that @a can store a C<Set of Apple>. We *can* answer your real question (about inheritance and compound types), but we have to start with the right declarations: my $a returns Set of Apple; my $b returns Basket of Fruit; or: my Set of Apple $a; my Basket of Fruit $b; and a generic assignment: $c = $a; $c = $b; Now we can fill in your list (which is somewhat expanded): Assignment OK? Because... ====================== === =============================== my Set $c = $a ok $c's type: Set (of Object) ^ ^ | | $a's type: Set of Apple my Set $c = $b ok $c's type: Set (of Object) ^ ^ | | $b's type: Basket of Fruit my Set of Fruit $c = $a ok $c's type: Set of Fruit ^ ^ | | $a's type: Set of Apple my Set of Fruit $c = $b ok $c's type: Set of Fruit ^ ^ | | $b's type: Basket of Fruit my Set of Apple $c = $a ok $c's type: Set of Apple ^ ^ | | $a's type: Set of Apple my Set of Apple $c = $b no $c's type: Set of Apple ^ X | | $b's type: Basket of Fruit my Basket $c = $a no $c's type: Basket (of Object) X ^ | | $a's type: Set of Apple my Basket $c = $b ok $c's type: Basket (of Object) ^ ^ | | $b's type: Basket of Fruit my Basket of Fruit $c = $a no $c's type: Basket of Fruit X ^ | | $a's type: Set of Apple my Basket of Fruit $c = $b ok $c's type: Basket of Fruit ^ ^ | | $b's type: Basket of Fruit my Basket of Apple $c = $a ok $c's type: Basket of Apple ^ ^ | | $a's type: Basket of Apple my Basket of Apple $c = $b no $c's type: Set of Apple ^ X | | $b's type: Basket of Fruit ^ As usual the | arrow between two classes represents the C<.isa> relationship. X And I've used the symbol | to represent the complementary C<.isnta> relationship. In other words, to be able to assign a C<Righty> object to a C<Lefty> variable (or use a C<Righty> in any other context where a <Lefty> is expected): my Lefty $var = Righty->new(); each component of type C<Righty> must be in a valid C<.isa> relationship to the corresponding element of C<Lefty>. In other words: my X of Y of Z $var = (A of B of C)->new(); is only permitted if: A.isa(X) && B.isa(Y) && C.isa(Z) Hope that helps. Damian