in reply to Experimenting with Lvalue Subs

Have a look at Class::Accessor::Lvalue and a discussion of Lvalue accessors, in which you can find my own slightly different take on it, which I might put on CPAN.

Just on what you've written here, I think

$obj->get_set( 'name' ) = 'Limbic';
is not a great idea as it gives you many of the problems of direct hash access. It seems to me that creating individual Lvalue methods for each field in you object gives you run time checking without having to write a key_ok() sub and it also gives you overridability.
$obj->name = 'Limbic';
seem much nicer to me (although I prefer fields to have an initial capital letter).

As for getting the rvalue, it's possible but it's not pretty! Basically you use a tied scalar as the lvalue and then when it gets assigned into, you can see the rvalue and you can do whatever tricks you like. In my own class and also in C::A::L when the tied object is written to or read from it just calls the setter or getter method respectively. This gives you full overridability, just override the default setter method.

There's lots of overhead but you can do cool stuff like a two-way hash, for example:

$dept->Positions("manager") = "bill"; print $dept->People("bill")."\n"; # manager
here we have overridden setPositions, getPositions, setPeople and getPeople so that each of the setters updates 2 hashes internally, 1 mapping from People to Positions and the other mapping the opposite direction. The getters just read from the relevant hash.

2005-01-29 Janitored by Arunbear - fixed hard-coded pm link, as per Monastery guidelines

Replies are listed 'Best First'.
Re^2: Experimenting with Lvalue Subs
by Limbic~Region (Chancellor) on Jan 24, 2005 at 23:09 UTC
    fergal,
    Have a look at...

    *Chuckle* One of the first points I made was that instead of fixing the implementation of Lvalue subs, people chant the mantra:

    • 1. Don't do that
    • 2. If you are going to do that, use a ready made wheel
    • 3. If you insist doing it yourself, you will need to tie it which makes it S-L-O-W

    If we are going to revert to other wheels, I personally prefer Attribute::Property and even discussed how to overcome some of its limitations. It doesn't fix the fact that a core feature is pretty much unuseable in the current form.

    As for getting the rvalue, it's possible but it's not pretty!
    Not really. I already mentioned that tying is the last ditch effort in the mantra and I am well aware of how to do it. The trouble is that you are not getting at the rvalue inside the sub which makes tying necessary. The point of the meditation is to spark interest in correcting this deficiency, not more work arounds.

    Unfortunately I am not a competent C programmer, but TimToady indicated elsewhere in this thread that he wasn't opposed to the change as long as it was in alignment with p6. And all this time I was assuming the trouble would be with getting it past p5p not the patch itself.

    Cheers - L~R

      Indeed, sorry for not reading more carefully. However my comment isn't entirely void, have a look at Apocalypse 6 where Larry says that lvalue subs will not get to see their rvalue unless they use tieing
      If you need to do pre- or post-processing on the "public" value, however, you'll need to return a tied proxy variable.
      and he also said that the tieing will be easy. He has other plans (temporizing - basically a tie interface to local) that would break if it was done the way you want.

      There's still also the issue of potentially surprising order of evaluation.