in reply to Re: Re: lvalue subs return undef, playing with experimental features, the End of the World, etc
in thread lvalue subs return undef, playing with experimental features, the End of the World, etc

If you check the perlsub section of the manuals, you get a very brief introduction to the "lvalue" feature. Here is the example:
my $val; sub canmod : lvalue { $val; } sub nomod { $val; }
This isn't terribly helpful, is it? Yet it does illustrate how you are just supposed to leave it there. Perl subroutines normally work such that the last thing left on the stack gets returned, but in the case of an lvalue-enabled subroutine, there must be a special handler that converts the stack entry into a kind of reference which can be assigned to.

Try colapsing your logic into an unfortunately ugly ?: chain:
my %foo; my $bar; sub foo : lvalue { my ($key) = @_; if (some_complex_condition()) { do_some_stuff($foo{a}); $key = "b"; } if (other_complex_condition()) { $foo{a} .= do_some_other_stuff($foo{b},$foo{c}); $key = "a"; } defined($key)? exists($foo{$key})? $foo{$key} : $foo{$key} = undef : $bar; }
First, figure out what you need to return, taking as much time as is necessary. Then, once you know, shuffle the appropriate variable to the top of the stack and leave it there.
  • Comment on Re^3: lvalue subs return undef, playing with experimental features, the End of the World, etc
  • Select or Download Code

Replies are listed 'Best First'.
Formatting chained and nested ternary ops (was Re^4: lvalue subs return undef....)
by demerphq (Chancellor) on May 07, 2002 at 11:40 UTC
    an unfortunately ugly ?: chain:

    It need not be quite so ugly. Reverse the first test so you get a chained ternary nstead of a nested ternary. Then parenthesize the tests and line up the ? and : vertically and it becomes a whole lot easier to read (IMO).

    (!defined($key)) ? $bar : (exists($foo{$key})) ? $foo{$key} : $foo{$key} = undef;
    Incidentally I'm betting you format your code using some kind of automatic indenter (cperl-mode perhaps?) In my experience code formatters do awful things to chained and nested ternary ops. So format em by hand and you get much more readable results.

    :-)

    Yves / DeMerphq
    ---
    Writing a good benchmark isnt as easy as it might look.