SPUG: first vs //
Michael R. Wolf
MichaelRWolf at att.net
Wed Jul 18 11:37:42 PDT 2007
> Interestingly, Larry's 'first' suggestion is now available in the core:
>
> use List::Util qw/first/;
>
> $var = first { defined } $foo, $bar, $baz;
In the world of TMTOWTDI, I like.... *both*.
I initially liked the use of 'first' as more intuitive (for my definition of
intuitive). In reading the "old arguments", I realized that the 'first'
subroutine does not (in fact, cannot) do short circuiting, in which case the
// operator is better.
$var = $foo // $bar // $baz;
Short circuiting (lazy evaluation) makes much more sense when functions are
called since they could have a non-trivial cost and side-effects that may
need to be avoided. In some cases the later functions must be guarded
against execution if earlier ones succeed.
$var = foo() // bar() // baz();
A mixed example might be
$me_a_name_I_call_myself =
$ENV{USERNAME} //
$ENV{USER} //
getlogin() ||
getpwuid($UID) ||
qx( whoami | tr -d '\012' ) ||
qx( id --user --name | tr -d '\012' ) ||
'nobody';
This example mixes on two dimensions:
variable reference vs function call
|| vs //
As I was creating it, I realized that the arguments to qx() would have to
have the newlines removed to be consistent with the variable contents. And
I also realized that if they failed, they'd return an empty string.
I decided (arbitrarily, I'm open to suggestions) that an empty string would
be OK (i.e. defined-ness) from an environment variable, but NOT from a qx().
Kinda' arbitrary, I realize, but if someone went to the trouble of setting
an environment variable to be an empty string, it was probably for a reason.
I could argue the other side, too. Empty strings in variables should be
ignored in deference to a better choice.
$my_favorite_editor = qw(vi emacs)[rand 2];
$editor = $ENV{EDITOR} || $ENV{VISUAL} || $my_favorite_editor;
More information about the spug-list
mailing list