my @tab = ( 1, 3, 6..9 );
my $x = @tab;
my $y = ( 1, 3, 6..9 );
where I expected $x to be 6 (the number of items) and $y to be 9 (the last element), as documented in perldata. But before distributing the quiz I thought it was worth a test ... and indeed it was! To my surprise, $y turns out to be an empty string. It took me some time to find out why : with
my $y = ( 1, 3, 6, 7, 8, 9 );
the result is 9 indeed. But with
my $y = ( 1, 3, 6..9 );
the interpreter does not build the range in list context, and then keep the last element. What happens instead is that it throws away the beginning of the list (there is even a warning about that), and then evaluates
my $y = 6..9;
in scalar context; where 6..9 is no longer a range, but a flip-flop operator. Now since the left-hand side is true, that operator is supposed to be true, right ? Well, no, because 6 is a constant, and in that case, perlop tells us that the flip-flop is "considered true if it is equal (
==
) to the current input line number (the $.
variable)". So $y ends up being an empty string, while my $six = 6;
my $nine = 9;
my $y = $six..$nine;
would yield 1E0!
I couldn't be that nasty to the interviewed programmers, so in the end that question will not be part of the quiz.
Perl, a language for masochist programmers.
ReplyDeletethe filp-flop is too clever.
ReplyDeleteAn interesting article Laurent - shows the importance of testing.
ReplyDeleteOut of interest I looked up the flip-flop operator for Perl6. Perl6 does have one but its symbol is 'ff' so can't get confused with the range operator. http://perl6advent.wordpress.com/2011/12/05/the-flip-flop-operator/
But...there's no list context there; the title of the article is misleading.
ReplyDelete