Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Variable assignment error checking

by nathaniels (Acolyte)
on Dec 15, 2013 at 00:06 UTC ( [id://1067192]=perlquestion: print w/replies, xml ) Need Help??

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

Hello All!

I've been wracking my brain over a good way to do this in as few lines as possible and I feel like I'm missing something obvious. I'm trying to figure out how to do error handling with a variable assignment. I have a statement like this:

$var = func( $var );

If the function should fail, I would like the $var to stay the same, not be assigned to the failed 0 returned by the function. Is there a way to do this without creating a new variable to hold the value before the assignment?

Replies are listed 'Best First'.
Re: Variable assignment error checking
by davido (Cardinal) on Dec 15, 2013 at 02:24 UTC

    This is assuming that func() doesn't have any side-effects against its parameters.

    $var = func($var) || $var;

    ...unless I'm misunderstanding the question. ;)


    Dave

      davido has the answer. That's the way to do it. If func returns 0 or undef, $var will be assigned to $var, therefore keeping its original value. I use this technique all the time.

      A for will get you from A to Z; a while will get you everywhere.
        $cough ||= cough( $cough );
Re: Variable assignment error checking
by choroba (Cardinal) on Dec 15, 2013 at 00:24 UTC
    There are several ways. For example, instead of returning 0 on failure, throw an exception:
    sub func { my $arg = shift; die 'Invalid Argument' if $arg > 10; return $arg - 2; } eval { $var = func($var) }; # No exception catching. print "$var.\n";

    Another possibility might be to change the function to return two values: the result and success. Upon failure, the result would be the same as the input argument, but the success would be 0. Otherwise, the function would return the new result and 1:

    sub func { my $arg = shift; return($arg, 0) if $arg > 10; return($arg - 2, 1); } my $var = 10; ($var, my $succ) = func($var); print "$var.\n";

    Update: For numeric return values, you can just add a string to the number to indicate failure:

    sub func { my $arg = shift; return $arg . 'E0' if $arg > 10; return $arg - 2; }

    See Range Operators for a similar trick.

    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
      nice list, but why not changing the argument alias in place to only return the error code?

      DB<101> $var=2 => 2 DB<102> sub func { if ( $_[0] > 0 ) { $_[0]--; return OK_CODE; } return ERR_CODE; } DB<103> $err = func ($var); => "OK_CODE" DB<104> $err = func ($var); => "OK_CODE" DB<105> $err = func ($var); => "ERR_CODE"

      Cheers Rolf

      ( addicted to the Perl Programming Language)

Re: Variable assignment error checking
by rnewsham (Curate) on Dec 15, 2013 at 00:31 UTC

    I think changing the sub to return $var in event of it being unable to complete its intended purpose would be the best option.

    I don't like it but if changing the sub can't be done then this is the most consice method I could think of.

    use strict; use warnings; my $var = 'foo'; my $tmp; $var = ( $tmp = return_false() ) ? $tmp : $var; print "$var\n"; $var = ( $tmp = return_true() ) ? $tmp : $var; print "$var\n"; sub return_true { return 'bar'; } sub return_false { return; }
      It is arguably more readable to save off the old value, and re-instate it if func returns undef/zero:
      my $oldval; $val = func( $oldval=$val) || $oldval;
      Newer perl's allow the alternative of using the // (defined or) operator.

      To maintain the challange of "not creating a new variable", one could try:

      $val = func( $_=$val) || $_;
      Add a BLOCK, if $_ is being abused:
      $val = do{ func( local $_=$val) || $_ };

                   When in doubt, mumble; when in trouble, delegate; when in charge, ponder. -- James H. Boren

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1067192]
Approved by rnewsham
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (2)
As of 2024-04-19 20:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found