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

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to