raybies has asked for the wisdom of the Perl Monks concerning the following question:

I've got a sub that returns two arguments if it succeeds, and a single 0 if it fails...

I wanna know a quick single line way I can state:

if (my ($x, $y) = mysub ($args)) { #returned defined pairs do stuff... } else { #returned single zero. do other stuff... }

Essentially I want to return multiple values--but if they're not all returned, then use that as a function failed condition. Of course this is probably breaking all the programming rules of the universe by wanting to do this... but then again... I'm okay with that.

Currently even when I return 0, if it's written above, it thinks it's passed.

Thanks! --Ray

Replies are listed 'Best First'.
Re: if multiple arg return or single fail?
by ikegami (Patriarch) on Mar 07, 2011 at 16:39 UTC

    Can you return an empty list on failure?

    sub mysub { ... ... or return (); ... return ( $x, $y ); }

    If so, your code will work as is. List assignment in scalar context returns the number of elements to which the RHS evaluates. That means if the function return zero values, the assignment returns zero to the "if".

    Currently even when I return 0, if it's written above, it thinks it's passed.

    That's one value, so the assignment returns one.

      Thanks, Ikegami! Hooked on Perlmonks worked for me. :) --Ray
Re: if multiple arg return or single fail?
by JavaFan (Canon) on Mar 07, 2011 at 17:08 UTC
    Note that the top level operator in the if() statement is an list-assignment. List-assignment returns the number of items on the right-hand side of the assignment. So only if mysub returns an empty list, the else part will be executed.

    Now, you can get the value of $x by using:

    if ((my ($x, $y) = mysub ($args))[0]) {
    but I don't think there's an easy way to say "mysub returns at least 2 values, or a non-zero value" while at the same time declaring and assigning those values to variables all in one go. But if you take the declaration out:
    my ($x, $y); if ((($x, $y) = mysub ($args)) != 1 || !defined($x) || length($x) != 1 + || $x != 0) { do stuff } else { # Triggered on a single 0 do other stuff }
    Whether this is the most readable solution, I'm not so sure.
      Buwahahaha! That's brilliant stuff, Javafan. I've used the (bunch-o-stuff)[0] approach before, but had really thought to use it in that context. Good stuff... Thanks! --Ray
Re: if multiple arg return or single fail?
by toolic (Bishop) on Mar 07, 2011 at 16:42 UTC
    my ($x, $y) = mysub(); if (defined $x and defined $y) { # do stuff... } else { #returned single zero. # do other stuff... }
      Yeah, that works, but I wanted it all... in a single line if line. So, I decided to go with changing the function to return an empty list. Thanks guys!
Re: if multiple arg return or single fail?
by jethro (Monsignor) on Mar 07, 2011 at 16:48 UTC

    One line for two 'do stuff's? Not possible ;-). But it might look best with this design:

    errorstuff if ((my ($x, $y) = mysub ($args))==1); do stuff;
Re: if multiple arg return or single fail?
by anonymized user 468275 (Curate) on Mar 07, 2011 at 16:55 UTC
    $x is zero but defined, $y undefined in the error case:
    my ( $x, $y, $z ) = mysub( @args ); if ( $x or defined( $y )) { .... do stuff } else { .... handle error }

    One world, one people

Re: if multiple arg return or single fail?
by mellon85 (Monk) on Mar 07, 2011 at 17:22 UTC
    sometimes I Just miss the Maybe Monad...