in reply to return if 0

The last statement executed is return if 0;. The return may not have been executed, but the statement did. An if statement whose condition evaluates to something false, evaluates to that something.

(I believe the last sentence is undocumented behaviour.)

Replies are listed 'Best First'.
Re^2: return if 0
by massa (Hermit) on Jun 22, 2009 at 18:24 UTC
    perl -E 'sub result { return 1 if "0" } say result'
    yields
    0
    and
    perl -E 'sub result { return 1 if "0 but true" } say result'
    yields
    1
    thus proving your statement :-D
    []s, HTH, Massa (κς,πμ,πλ)
      Not really, but the following does:
      $ perl -MData::Dumper -e'print Dumper sub{return 1 if $_[0]}->(undef)' $VAR1 = undef; $ perl -MData::Dumper -e'print Dumper sub{return 1 if $_[0]}->(0 )' $VAR1 = 0; $ perl -MData::Dumper -e'print Dumper sub{return 1 if $_[0]}->("0" )' $VAR1 = '0'; $ perl -MData::Dumper -e'print Dumper sub{return 1 if $_[0]}->("" )' $VAR1 = '';

      Update: Switched to DD to show the difference between string zero and numerical zero.

        Look how interesting:
        $ perl -MData::Dumper -e 'print Dumper (do { 1 if $_ }) for undef, 0, +"0", ""' $VAR1 = undef; $VAR1 = 0; $VAR1 = '0'; $VAR1 = ''; $ perl -MData::Dumper -e 'print Dumper ($_ and 1) for undef, 0, "0", " +"' $VAR1 = undef; $VAR1 = 0; $VAR1 = '0'; $VAR1 = ''; $ perl -MO=Concise -e 'sub a { 1 if $_ } print a for undef, 0, "0", "" +' k <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 2 -e:1) v:{ ->3 3 <;> nextstate(main 2 -e:1) v:{ ->4 j <2> leaveloop vK/2 ->k a <{> enteriter(next->g last->j redo->b) lK/8 ->h - <0> ex-pushmark s ->4 - <1> ex-list lKM ->9 4 <0> pushmark sM ->5 5 <0> undef s ->6 6 <$> const[IV 0] sM ->7 7 <$> const[PV "0"] sM ->8 8 <$> const[PV ""] sM ->9 9 <#> gv[*_] s ->a - <1> null vK/1 ->j i <|> and(other->b) vK/1 ->j h <0> iter s ->i - <@> lineseq vK ->- f <@> print vK ->g b <0> pushmark s ->c e <1> entersub[t2] lKS/TARG,1 ->f - <1> ex-list lK ->e c <0> pushmark s ->d - <1> ex-rv2cv sK/128 ->- d <#> gv[*a] s ->e g <0> unstack v ->h -e syntax OK $ perl -MO=Concise -e 'sub a { $_ and 1 } print a for undef, 0, "0", " +"' k <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 2 -e:1) v:{ ->3 3 <;> nextstate(main 2 -e:1) v:{ ->4 j <2> leaveloop vK/2 ->k a <{> enteriter(next->g last->j redo->b) lK/8 ->h - <0> ex-pushmark s ->4 - <1> ex-list lKM ->9 4 <0> pushmark sM ->5 5 <0> undef s ->6 6 <$> const[IV 0] sM ->7 7 <$> const[PV "0"] sM ->8 8 <$> const[PV ""] sM ->9 9 <#> gv[*_] s ->a - <1> null vK/1 ->j i <|> and(other->b) vK/1 ->j h <0> iter s ->i - <@> lineseq vK ->- f <@> print vK ->g b <0> pushmark s ->c e <1> entersub[t2] lKS/TARG,1 ->f - <1> ex-list lK ->e c <0> pushmark s ->d - <1> ex-rv2cv sK/128 ->- d <#> gv[*a] s ->e g <0> unstack v ->h -e syntax OK
        Conclusion: $_ and 1 and 1 if $_ is exactly the same thing. perl compiles it to the same bytecode.
        []s, HTH, Massa (κς,πμ,πλ)

      Interesting! The last expression evaluated is the string "0". That's false, so the return doesn't fire, but the "0" is actually returned.

      Cool example, thanks!

      -- zigdon