in reply to Re: Elegant way to return true or nothing from a subroutine?
in thread Elegant way to return true or nothing from a subroutine?

undef isn't the same as "nothing":

#!/usr/bin/perl -w use strict; sub ret_undef { return undef } sub ret_nothing { return; } print ret_nothing(), "\n"; print ret_undef(), "\n"; my @foo = ret_nothing(); print "Elements in foo: ", scalar @foo, "\n"; print @foo; my @bar = ret_undef(); print "Elements in bar: ", scalar @bar, "\n"; print @bar;

Replies are listed 'Best First'.
Re^3: Elegant way to return true or nothing from a subroutine?
by GrandFather (Saint) on Oct 10, 2006 at 02:14 UTC

    Are you sure? Consider:

    use strict; use warnings; use Data::Dump::Streamer; my $value = undef; print !!$value; my $nothing = nothing (); my $retNothing = retNothing (); my $retUndef = retUndef (); my $retFalse = retFalse (); my $retFalse2 = -retFalse (); Dump (\$nothing); Dump (\$retNothing); Dump (\$retUndef); Dump (\$retFalse); Dump (\$retFalse2); sub nothing { } sub retNothing { return; } sub retUndef { return undef; } sub retFalse { return 1 == 0; }

    Prints:

    $SCALAR1 = \do { my $v = undef }; $SCALAR1 = \do { my $v = undef }; $SCALAR1 = \do { my $v = undef }; $SCALAR1 = \do { my $v = '' }; $SCALAR1 = \do { my $v = 0 };

    Updated to add two false cases

    and in list context :)

    ... my @nothing = nothing (); my @retNothing = retNothing (); my @retUndef = retUndef (); my @retFalse = retFalse (); my @retFalse2 = -retFalse (); Dump (\@nothing); Dump (\@retNothing); Dump (\@retUndef); Dump (\@retFalse); Dump (\@retFalse2); ...

    Prints:

    $ARRAY1 = []; $ARRAY1 = []; $ARRAY1 = [ undef ]; $ARRAY1 = [ '' ]; $ARRAY1 = [ 0 ];

    DWIM is Perl's answer to Gödel

      Try it in list context.

        In the section "Returning Failure," PBP recommends using a bare return to signify failure. There is a two page discussion there, explaining that, at the hands of the caller, the returned undef can easily turn into the one-element list (undef) and evaluate to true.
        sub foo { return undef;} sub bar { return;} if (my @foos = foo()) { print "foo() is so true...\n"; ## surprise! } else { print "foo() is false.\n" } if (my @bars = bar()) { print "bar() is true...\n"; } else { print "bar() is false.\n" }