There are some situations where one will commonly get a return value of true, false, or undef and each needs to be handled distinctly. Two examples off the top of my head are fork and wantarray. I'm wondering what idiom monks use for this situation since I've never quite been satisfied with my own ways.

For fork, I used to write this most often:

my $pid = fork; die "can't fork: $!" if ! defined $pid; if ( $pid ) { # parent } else { # child }

With Perl 5.10, this gets a little easier.

use 5.010; my $pid = fork // die "Can't fork: $!"; if ...

That's one less statement, and it reads neatly "fork or die".

use 5.010; given ( fork ) { when ( undef ) { die "Can't fork: $!"; } when ( !$_ ) { # child } default { # parent my $child_pid = $_; } }

One thing I don't like about using given/when for this is that it's hard to rearrange the clauses. I can't say "when ($_)" because it's always true, even when $_ is false. That's a problem common to this situation, however. You can't just take "false" as false, since it might also be undef. That is, one always has to check defined before falsehood.

About all this has going for it is I only create a $pid variable where I need it (in the parent). This seems clumsy for fork, but it might make more sense for wantarray.

use 5.010; given ( wantarray ) { when ( undef ) { return; # void context } when ( !$_ ) { return 'scalar context'; } default { return qw( list context ); } }

That's good if I really need a block for each condition to take different actions in the different situations. On the other hand, if all I'm doing is selecting a return value base on context, the ternary seems ready-made.

return wantarray ? qw( list context ) : defined wantarray ? 'scalar context';

Maybe I should have a function hide the mess and make a call to it be my idiom.

return tfu( wantarray, true => sub { 'true' }, false => sub { 'false' }, undef => sub { 'undef' }, ); sub tfu { my $value = shift @_; my %todo_for = @_; return $value ? $todo_for{ true }->() : defined $value ? $todo_for{ false }->() : $todo_for{ undef }->(); }

I can put my "clauses" in any order, and the sub will figure it out. I can pile into the sub defaults and validation and whatever else. That's a far cry from a convenient idiom, however.

At this point, I think I've just thought about this too much. I wonder what others think.


In reply to An idiom for selecting true, false, or undef. by kyle

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.