One of the wise may override my evaluation,
Or I could do it. ;-)
Can the type of a variable vary independenty of its value?
My understanding is that the type of a variable merely restricts the type
of value you can assign to it. (Well, it probably does more, but I'm not
clear on what or how yet.)
There are in fact *two* types associated with any Perl variable:
1. Its "storage type" (i.e. the type(s) of value it can hold)
This is specified before the variable or after an C<of> or C<returns>.
It defaults to Scalar.
2. Its "implementation type" (i.e. the class that tells it how to act)
This is specified after an C<is>. It defaults to the type indicated
by the variable's sigil.
So:
Declaration Storage Implementation
Type Type
=========== ======= ==============
my $var; Scalar Scalar
my @var; Scalar Array
my %var; Scalar Hash
my Int @var; Int Array
my @var of Int; Int Array
my @var returns Int; Int Array
my @var is SparseArray; Scalar SparseArray
my Int @var is SparseArray; Int SparseArray
my @var is SparseArray of Int; Int SparseArray
my @var is SparseArray returns Int; Int SparseArray
BTW, the use of C<returns> may seem a little odd, until you realize that,
like a subroutine, a variable is just an access mechanism for values.
There's rather a nice node on PerlMonks just now about just that notion.
Consider the following:
my @a = (1,2,3);
my $b := @a;
@a and $b both refer to the same object. $b's object has methods such as
PUSH, POP, etc, as does @a's.
Do they? One is obviously an array, and one is obviously a scalar.
You may get an error (cannot alias an array as a scalar) or $b get aliased
to the array-in-scalar-context (a reference).
The latter, in fact. When trying to puzzle out what any binding does
imagine that the LHS is a subroutine parameter, and the RHS the corresponding
argument.
my @a = (1,2,3) but implements_sum_method; # add .sum method to vtable
my SummingArray $b := @a;
Actually, (unless implements_sum_method is a subclass of SummingArray,)
That won't help. Value (i.e. C<but>) properties don't confer class status.
it looks like an error to me, because @a is an array and/or an
implements_sum_method, but $b is restricted to holding a SummingArray.
Yep.
As counter-example, consider:
my Array @array := SpecialArray.new;
Should the value in @array act like an Array or a SpecialArray? Most
people would say SpecialArray, because a SpecialArray ISA Array.
Weeeeeell...*I'd* say that @array should act like an Array (that is, you should
only be able to call the methods specified by the Array class), except that
any method calls should be polymorphically resolved to invoke the
equivalent SpecialArray methods.
But maybe that's just saying the same thing. Is there a linguist in the house?
;-)
I can also interpret what you want as saying "my SpecialArray @array :=
Array.new" should autopromote the value to a subclass somehow which would
be very strange.
To say the least!
Damian