This was originially a response to Re^2: lvalue considered harmful..., but in writing it, a bigger question arose.

Does anyone use lvalue subs? If so, for what?

I realise that the these were added as and remain an experimental feature, but they must have been added for a reason. I'm just wondering what the reason was. As they are, the only thing that can be done with the assigned value is ... well, to assign it to something. Sure, you can decide what to assign it to using the values past via the normal @_ mechanism to make the determination, but there is absolutely no way to inspect the value of the assign value either before you assign it nor after is was assigned. That means it is impossible to perform any verification on the assigned value. This may work for things like substr and splice, that simply don't care what is assigned, but it makes using lvaue subs for any other purpose pretty much useless. I note that vec can and does inspect the value assigned in that it will reject non-numerical assignments as it has to process them in order to use them. This is exactly the facility I would like to use.

To me, this makes the utility of :lvalue pretty much non-existant. Which is a shame, because I think that the semantics of lvalue subs has a lot going for it.

I don't see any reason why the assigned value shouldn't be made available to the sub through any one of a number of mechanisms:

  • Prepended or appended to the @_ array with unshift or push much as is currently done with $self in methods.

    I can see how this could break existing code though.

  • Made available to the sub under the same name as the sub itself as is done in some languages.

    Without thinking about it very hard, localising the typeglob for the subs name could be used as the mechanism for this, but as I am not familiar with Perl internals, this might not be as simple as it is apparently obvious (to me).

  • Aliasing the assigned value using $_, localised for the duration of the sub seems a fairly perlish idea to me.

    If this was only done for lvalue subs, I cannot see it breaking any existing code. However, this would restrict assignment to a single value which doesn't seem so perlish, but (from my experimentation so far) appears to be a restriction with the current implementation for user defined subs.

    my @test; sub test{ @test }; test() = (1..10); my @array = test() = (1..10);

    both give the error msg "Can't return array to lvalue scalar context", which suggests that the second line ought to work, but doesn't recognise the context correctly?

    There is a precedent for assigning a list to an lvalue sub namely splice, but I've failed to get it to work for my own subs.

  • Utilising one of the currently unused $^x vars similar to $^N for the extended regex (?{}) construct.

    A quick scan of perlop suggests that as of perl v5.6.1, that the following $^x vars are unused: BGJKNQUYZ.

    Though perhaps the most obvious (and vaguely mnemonic: Like $_, but different :^) would be $^_ which is available and assignable.

    This could be extended to be @^_ if list assignment were/is possible

Of these mechanisms, I like the alising of the subs name the best I think. It seems a fairly natural mechanism that $subname[0] would alias the (first) value assigned to an lvalue sub and @subname would alias the list of values assigned to the an lvalue sub. It has the virtue of not clashing with any existing mechanism as far as I can see. It has the possible downside that as a new mechanism it might be hard to implement?

Using @^_ and/or $^_ would be my second choice.

I would be interested to hear about anyones experience of using the current implementation of lvalue subs successfully, as well as comments on my thoughts for extending it. Also, if anyone thinks or knows if this would be likely to be accepted as a patch for a perl 5 ( I assume something better will be in place for perl 6), and any thoughts on how hard that would be to do.


Examine what is said, not who speaks.

update (broquaint): added <readmore> tags