#!/usr/bin/perl
use strict;
use warnings;
sub x { local$,=" "; print "$_[ 0 ]:", map( "[$_]", @_[ 1 .. $#_ ] ),
+"\n" }
x "for", sub { for( 5 .. 7 ) { 1 } }->();
x "while(5)", sub { while( 5 ) { 1; last } }->();
x "while(0)", sub { while( 0 ) { 1 } }->();
x "if(5)", sub { if( 5 ) { 1 } }->();
x "if(0)", sub { if( 0 ) { 1 } }->();
x "do{}while(0)", sub { do { 1 } while 0 }->();
x "do{}until(5)", sub { do { 0 } until 5 }->();
__END__
for: []
while(5):
while(0):
if(5): [1]
if(0): [0]
do{}while(0): [1]
do{}until(5): [0]
I admit the value returned from the function for surprised me. It returns an honest-to-goodness false (ie. an empty string) -- not even undef. (I checked.) Interesting.
Also somewhat surprising, but not nearly as much, is that the functions with while return nothing at all.
Because I knew about the behaviour of if – when the condition is the last thing evaluated, it is returned, while when the body runs, its last expression's value is returned.
Which is exactly as expected by the model I described. Which is exactly what perlsub describes:
The return value of a subroutine is the value of the last expression evaluated by that sub, or the empty list in the case of an empty sub.
I guess Perl is simply inconsistent here.
Update: per Re: "last expression" quiz, I added do{} pseudo-loop tests. They return a code reference. It’s probably safe to say that Perl simply has no rule, and that what you get back from a sub depends on implementation details of perl.
Update: gack, I forgot to invoke the do subs using ->. Fixed, thanks to robin in Re^4: "last expression" quiz. No wonder I got back coderefs. The actual behaviour does not seem very consistent either, though.
Makeshifts last the longest. |