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