Chip Salzenberg wrote:
> On Tue, May 16, 2006 at 03:24:20PM -0500, Patrick R. Michaud wrote:
>>>> sub foo($x is rw) {
>>>> $x = new SomeClass
>>>> }
>>>>
>>>> @z = 0..2;
>>>> foo( @z[1] );
>
> I sympathize with your desire for an answer, but it's probably a good idea
> for you to get the sample code and desired behavior right in all its Perl 6
> details before we go further. As for me, I'm not sure what the "=" in &foo
> is *supposed* to do in Perl 6. I think it does what you suggest, but I'm
> not entirely sure. And I'm even less sure whether ":=" in the same place
> would be legal, and if it were, what it would mean.
(Cc'ing perl6-compiler.)
The assignment does do what Patrick suggests.
If you change the assignment to a binding, it acts on the lexical pad of
&foo, changing the object $x points to, and does _not_ touch @z.
$x := new SomeClass;
$x = 123; # invalid, unless SomeClass handles "="
Note that even when $x =:= @z[1], these two lines are still different:
$x := new SomeClass; # an action on the pad
@z[1] := new SomeClass; # an action on @z
After either of the two operations, $x and @z[1] will no longer point to
the same thing. Conceptually, we say that binding is working on an
"upper level" than assignment. As a concrete example:
my @z = 0, 1, 2;
my $x := @z[1];
The layout now looks like the same as Patrick's example above (except
there is only one pad here):
Pad (::MY) -- <$x> Scalar -- Int (1)
-- <@z> Array -- [0] Scalar -- Int (0)
-- [1] Scalar -- Int (1)
-- [2] Scalar -- Int (2)
the $x Scalar and @x[1] Scalar are the same object:
$x =:= @z[1]; # True
variable($x).id == variable(@z[1]).id # True
now suppose we assign into $x; that invokes the Scalar object's
assignment method:
$x = new SomeClass;
Pad (::MY) -- <$x> Scalar -- SomeClass
-- <@z> Array -- [0] Scalar -- Int (0)
-- [1] Scalar -- SomeClass
-- [2] Scalar -- Int (2)
so both @z[1] and $x now contains an object of SomeClass. Now suppose
we bind $x away:
$x := new AnotherClass;
Pad (::MY) -- <$x> AnotherClass
-- <@z> Array -- [0] Scalar -- Int (0)
-- [1] Scalar -- SomeClass
-- [2] Scalar -- Int (2)
as you can see, $x and @z[1] no longer point to the same thing, as we
changed what <$x> means to the Pad. We can bind @z[1] away in the same
fashion:
@z[1] := 3.14159;
Pad (::MY) -- <$x> Scalar -- SomeClass
-- <@z> Array -- [0] Scalar -- Int (0)
-- [1] Num (3.14159)
-- [2] Scalar -- Int (2)
Note how that effectively makes @z[1] immutable:
@z[1] = 123; # error: Num doesn't handle assignment!
> I infer that in Perl 6, assigning '1' is at root the same problem as
> assigning 'new SomeClass', because morphing is *not* assumed to be an
> ability of most types, so it may be necessary to store a new value of a
> completely new type in the given target container.
Yes. Exactly.
Audrey
signature.asc
Description: OpenPGP digital signature
