[tpm] Is there a three-way version of...
John Macdonald
john at perlwolf.com
Mon Jun 1 09:54:05 PDT 2009
On Sat, May 30, 2009 at 02:54:13AM -0400, J. Bobby Lopez wrote:
> It basically looks like we're talking about switch statements. An alternate
> method of doing the same thing would be as follows, though I'm not sure how
> expensive it is:
>
> $a = "";
> $a = $b if $a = "";
> $a = $c if $a = "";
> $a = $d if $a = "";
> ...
> $a = "default" if $a = "";
This has a different meaning - you're testing for empty
string while // tests for undefined. The empty string is a
defined value. If would happen in my example below if the
command line had an arg of --foo= instead of --foo=0.
As far as expensive, consider how your version would read if,
instead of $a, you were setting a value nested deep in a hash.
The direct change to your form would be:
$my{$first}{$second}{option} = undef;
$my{$first}{$second}{option} = $b
unless defined $my{$first}{$second}{option};
$my{$first}{$second}{option} = $c
unless defined $my{$first}{$second}{option};
$my{$first}{$second}{option} = $d
unless defined $my{$first}{$second}{option};
$my{$first}{$second}{option} = 'default'
unless defined $my{$first}{$second}{option};
Using a temporary alias into the structure (as Uri suggests
in another message) that gets shorter:
my $alias = \$my{$first}{$second}{option};
$alias = undef;
$alias = $b unless defined $alias;
$alias = $c unless defined $alias;
$alias = $d unless defined $alias;
$alias = 'default' unless defined $alias;
But that's still a lot messier, harder to read, and more
expensive to execute than:
$my{$first}{$second}{option} = $b // $c // $d // 'default';
> On Fri, May 29, 2009 at 4:43 PM, John Macdonald <john at perlwolf.com> wrote:
>
> > On Fri, May 29, 2009 at 04:20:48PM -0400, Mike Stok wrote:
> > > As of perl 5.10 (I think) it is the "defined or" operator which only
> > > returns the right hand side if the left hand side is undef, from perlop:
> > >
> > > C−style Logical Defined‐Or
> > >
> > > Although it has no direct equivalent in C, Perl’s "//" operator is
> > > related to its C−style or. In fact, it’s exactly the same as
> > > "||",
> > > except that it tests the left hand side’s definedness instead of
> > > its
> > > truth. Thus, "$a // $b" is similar to "defined($a) || $b" (except
> > > that
> > > it returns the value of $a rather than the value of
> > > "defined($a)") and
> > > is exactly equivalent to "defined($a) ? $a : $b". This is very
> > > useful
> > > for providing default values for variables. If you actually want
> > > to
> > > test if at least one of $a and $b is defined, use "defined($a //
> > > $b)".
> > >
> > > The "||", "//" and "&&" operators return the last value evaluated
> > > (unlike C’s "||" and "&&", which return 0 or 1).
> >
> > This is especially useful for setting a value that can come from
> > multiple optional locations, and using the first one that was
> > actually provided:
> >
> > $foo = $opt{foo} || $ENV{PROG_FOO} || $rc_opts{foo} || 'default';
> >
> > and, as Mike said, this will still take the first one found even
> > if the explicitly provided value is 0 or ''. e.g.:
> >
> > prog --foo=0
> >
> > The || operator would skip this setting (because it's false) and
> > go on to getting the setting of foo from the alternate sources.
> > _______________________________________________
> > toronto-pm mailing list
> > toronto-pm at pm.org
> > http://mail.pm.org/mailman/listinfo/toronto-pm
> >
>
>
>
> --
> J. Bobby Lopez
> Web: http://jbldata.com/
> Twitter: http://www.twitter.com/jbobbylopez
More information about the toronto-pm
mailing list