Mark J. Reed writes:
> Let me just chime in with my support for John's basic idea.  I would
> definitely prefer that it be easy to arrange things such that
> 
>       $obj.foo = 'bar'
> 
> winds up invoking a method on $obj with 'bar' as an argument, rather
> than invoking a method on $obj that returns an lvalue to which
> 'bar' is then assigned.  (Yes, like Ruby's def foo=; I have a Rubyometer
> and I'm not afraid to use it!)  It doesn't need to be the default 
> rw accessor behavior, but I would like it to be accomplishable without
> jumping through a lot of hoops.

Okay, well, I thought that my example did that, but apparently using
C<will get> and C<will set> is a little too complex... (my sentiments
are beginning to follow Larry's, in that I'm not sure you know what you
want -- perhaps you could give a hypotheical syntax?)

So, what you really want is a way so that:

    $obj.foo = 'bar';

Is translated into:

    $obj.foo('bar');

When you get rid of C<$.foo> and replace it with a C<foo> method.

This is doable (without a syntax munge), but it requires some
cleverness.  First I'll do it by hand, then I'll wrap it up in a trait.
Please realize that all this I'm doing is an *implementation* of a very
easy usage.

    class Dog {
        class :FooProxy {
            has $.method;
            multi sub infix:= (FooProxy $proxy, Any $val) {
                $.method($val);
            }
        }
        method foo_call (?$arg) {
            # accessor code here
        }
        method foo ($self:) is rw { 
            FooProxy.new(method => { $self.foo_call($_) })
        }
    }

That should turn:

    $obj.foo = 'bar';

Into:

    $obj.foo('bar');

And now we want to wrap that up so we can just say C<is accessor>:

    role accessor {
        class :Proxy {
            has $.method;
            multi sub infix:= (Proxy $proxy, Any $val) {
                $.method($val);
            }
        }
        multi sub trait_auxiliary:is (accessor $a, &code is rw: ?$arg) {
            my sub access (::_ $self:) {
                Proxy.new(method => { code($self: $_) })
            }
            &code = &access;
        }
    }

There.  Now here's the important part: in order to *use* all this, you
import whatever module defines it, and then say:

    class Dog {
        method foo (?$arg) is accessor {
            # accessor code here
        }
    }

If that's not easy enough for you, well, you're probably out of luck.

Luke
            

Reply via email to