in reply to Re^2: A question about method return values and error checking
in thread A question about method return values and error checking

That's resolved trivially:
printf <<EOF, $os->name( long => 1 ) // 'unknown OS', $os->version // +'unknown version'; Operating System: %s Version : %s EOF
If you return empty strings on failure instead of undef, then you'd need to use || instead of //, which could cause issues if 0 is a potential return value. (Not likely in the specific example of OS name/version, but relatively common in the general case.) So, personally, I'd chalk that up as another point in undef's favor.

Replies are listed 'Best First'.
Re^4: A question about method return values and error checking
by kennethk (Abbot) on Nov 05, 2015 at 15:13 UTC
    The discussion was about concerns that return undef; in list context returns a list that is one element long, and thus true. In contrast, a bare return; in list context returns a zero-length result. This is a point that is lost on many acolytes. return undef; might bite you if you naively did something like:
    my @names = $os->name( long => 1 ) or next; # No names
    On the other hand, of you did
    my @names = map $_->name( long => 1 ), @oses;
    you would end up with lists of different lengths with the bare return;. Your solution puts the list elements back in scalar context, and thus avoids the actual question.

    Update: I remembered where it really bites people:

    my %hash = (name => $os->name( long => 1 ), version => $os->version, );
    where the mismatch has now resulted in a transposition of keys and values.

    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

      my @names = $os->name( long => 1 ) or next;

      That seems more like a strawman to me. I just haven't run into code where people do list assignments in boolean context when using a sub that just returns a single scalar. It is an unnatural construct.

      While using a scalar-returning sub as part of some list is done very often.

      So subs that never return more than 1 scalar should never use return;. Subs that clearly return a list should avoid using return undef; to indicate failure.

      - tye        

        I concur that it's a poor example, but I'm a bit pressed to come up with a good example to demonstrate why it's good practice. Ultimately, I think we agree on what good form should probably be. Maybe if I mull it for a while, I can come up with a better justification.

        #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

      Yes, agreed. I misunderstood your earlier reply to me as having been concerned about the lack of default placeholder strings on failure rather than with what it does to the structure of lists with positional dependencies (such as hashes and printf arguments).

      Fortunately, the solution presented in my previous reply resolves both of these issues.

Re^4: A question about method return values and error checking
by Anonymous Monk on Nov 05, 2015 at 09:57 UTC

    The OP had an oops moment when some (poorly documented?) method was mis-used. A blank return; could make that oops even worse, in a list context. Thence the recommendation to go with return undef.