All these three perform the same way:
#! perl -slw use strict; sub morefoo{ $_[0] * 3 } sub a { my $x = shift; return defined $x ? morefoo( $x ) : undef; } sub b { my $x; return defined( $x = shift ) ? morefoo( $x ) : undef; } sub c { return morefoo( shift // return undef ); } print "$_ :> ", a( $_ ) for undef, 0, 1 ; print "$_ :> ", b( $_ ) for undef, 0, 1 ; print "$_ :> ", c( $_ ) for undef, 0, 1 ; __END__ C:\test>junk93 Use of uninitialized value $_ in concatenation (.) or string at C:\tes +t\junk93.pl line 21. Use of uninitialized value in print at C:\test\junk93.pl line 21. :> 0 :> 0 1 :> 3 Use of uninitialized value $_ in concatenation (.) or string at C:\tes +t\junk93.pl line 23. Use of uninitialized value in print at C:\test\junk93.pl line 23. :> 0 :> 0 1 :> 3 Use of uninitialized value $_ in concatenation (.) or string at C:\tes +t\junk93.pl line 25. Use of uninitialized value in print at C:\test\junk93.pl line 25. :> 0 :> 0 1 :> 3
The last is the 'cleanest', though less than intuitive.
The problem with a defined-and construct is that you need to retain the tested value for use on the right-hand side of the construct.
Unlike the defined-or where the defined value is the required result for the left-hand side; or you know it must be undef and so do not need to retain it for the right-hand side.
In reply to Re: What's the opposite of // (err) operator?
by BrowserUk
in thread What's the opposite of // (err) operator?
by John M. Dlugosz
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |