Darren Duncan writes:
> I need some clarification on the semantics of subroutine or method 
> return statements, regarding whether copies or references are 
> returned.  It will help me in my p6ification of p5 code.
> 
> Say I had a class with 3 private attributes, named [$:foo, @:bar, 
> %:baz], and I was making an explicit accessor for returning the full 
> values of each.
> 
> Take these 3 example method statements:
> 
>   return $self.foo;
>   return $self.bar;
>   return $self.baz;
> 
> For each of the above cases, is a copy of or a reference to the 
> attribute returned?  For each, will the calling code be able to 
> modify $obj's attributes by modifying the return values, or not?

Well if you're making accessors, why the heck are you making them
private?  But I can't really answer your question, because it depends on
how you write the accessors.

I'll answer your question by rephrasing it to use `$.foo`, [EMAIL PROTECTED],
`%.baz`.  Assume they are all declared with `is rw`:

    a)  my $x = $obj.foo;
    b)  $obj.foo = $x;
    d)  my $ref = \$obj.foo;
    e)  $$ref = $x;

    a)  my @x = $obj.bar;   # @x is now a copy, because = copies
    b)  @obj.bar = (1, 2, 3);
    c)  @obj.bar[2] = 3;
    d)  my $ref = $obj.bar;
    e)  @$ref = (1, 2, 3);

    a)  my %x = $obj.baz;
    b)  %obj.baz = (a => 1, b => 2);
    c)  %obj.baz{b} = 2;
    d)  my $ref = $obj.baz;
    e)  %$ref = (a => 1, b => 2);

These are all legal.  If you don't declare your attributes with `is rw`,
then the "b"s, "c"s (perhaps), and the "e"s are illegal.

Now back to your question.   You could write rw accessors for each of
your private variables that behave like the ones above like so:

    sub foo() is rw { $:foo }
    sub bar() is rw { @:bar }
    sub baz() is rw { %:baz }

If you want to intercept the write and do something with it, you can do
this (see S06 for details):

    sub foo() is rw {
        new Proxy:
            FETCH => sub ($self) { $:foo },
            STORE => sub ($self, $val) { 
                        say "Setting to $val"; 
                        $:foo = $val;
                     };
    }

Luke

Reply via email to