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

Well i found something weird:
anarion@foo:~$ perl -le 'sub a{my$c=pop;print $c;$c*a($c-1)unless!$c}p +rint a(--$ARGV[0])' 5 4 3 2 1 0 24 anarion@foo:~$ perl -le 'sub a{my$c=pop;print $c;$c*a($c-1)if$c}print +a(--$ARGV[0])' 5 4 3 2 1 0 0


jeffa has tried and have weird results printing 120 too, its a bug or i'm missing something?
I have perl 5.6.1 in a linux.

$anarion=\$anarion;

s==q^QBY_^=,$_^=$x7,print

Replies are listed 'Best First'.
Re: isn't unless ! $c the same than if $c ?
by Chmrr (Vicar) on Apr 03, 2002 at 23:32 UTC

    This is because of the return value of a subroutine in the absence of a return statement; it is the value of the last statement. In this case, both if and unless have truth values of whatever their argument is if they fail. If they succeed, their truth value is the last statement inside their block. That is:

    sub b{unless (!pop) {"unless"} } sub c{if (pop) {"if" } } print "failed if (0): ",c(0), "\n"; print "failed unless (0): ",b(0), "\n"; print "succeeded if (42): ",c(42),"\n"; print "succeeded unless (42): ",b(42),"\n";

    prints:

    failed if (0): 0 failed unless (0): 1 succeeded if (42): if succeeded unless (42): unless

    In this context, it makes sense -- when the conditional is not met, it falls though, and a() returns the last value in the subroutine -- in the "if" case, the value of $c, which is 0. In the case of the unless, it returns the value of !$c, which is 1.

    Update: Added two more cases to the example to make it clearer.

    perl -pe '"I lo*`+$^X$\"$]!$/"=~m%(.*)%s;$_=$1;y^`+*^e v^#$&V"+@( NO CARRIER'

(MeowChow) Re: isn't unless ! $c the same than if $c ?
by MeowChow (Vicar) on Apr 03, 2002 at 23:41 UTC
    The recursive return value for the $c == 0 case in both code samples is not properly specified, so the return value is set to the value of the compared expression, !$c in the first case, and $c in the second. What you should have written was something like:
      
    perl -le 'sub a{my$c=pop;print $c;$c?$c*a($c-1):1}print a(--$ARGV[0])' + 5
       MeowChow                                   
                   s aamecha.s a..a\u$&owag.print