Re: Friday Code Quiz
by trantor (Chaplain) on Sep 21, 2001 at 15:35 UTC
|
Invisible(ish) answer ahead, select with your mouse or have a look at the source to view it:
| $i contains 1, because, due to precedence,
the expression is treated as
(($i = 1),(2))
which is legal and this expression itself returns 2 in scalar context (the last element), and it returns
(1, 2) otherwise. |
Am I right? :-)
-- TMTOWTDI
| [reply] [d/l] [select] |
|
|
| [reply] |
Re: Friday Code Quiz
by davorg (Chancellor) on Sep 21, 2001 at 16:24 UTC
|
There have already been some correct answers in the
thread, but here's a full explanation.
|
Stage 1: People who run the code see that $i is
set to 1. They then try to come up with an explanation. One
common one I've seen is that they claim that the comma
operator returns its left operand in scalar context.
This gives them the right answer, but for the wrong
reason.
Stage 2: Other people realise that the comma operator
returns its rightoperand in scalar context. This
means that $i should be set to 2. This makes
sense, but is disproved by the evidence.
Stege 3: Finally, we reach for the precedence table and
realise that Perl is parsing the expression as
($i=1),2;.
It's worth pointing out that -w gives a
helpful warning, but also that B::Deparse is a useful
tool in investigating weirdness like this:
perl -MO=Deparse -e'$i=1,2' |
--
<http://www.dave.org.uk>
"The first rule of Perl club is you don't talk about
Perl club."
| [reply] [d/l] |
|
|
As evidenced by the output of the following one-liner:
| perl -e 'sub bob { $i=1,2;} print $i, "\t", scalar bob, "\n";' |
If I've learned one thing about interpreting obfu, it's that if I can't immediately tell what a line of code does, make it a subroutine and observe its behavior in isolation.
Spud Zeppelin * spud@spudzeppelin.com
| [reply] [d/l] |
|
|
Though I usually don't have useless constants in a void context, I might use that sort of construct for loop control (among other things) if you want something else to happen before
the control statement, and you don't want to waste
space on a whole 'if' block, e.g.:
$success = 1, last if something();
# And I know TMTOWTDI but you get the idea
$success = something() and last;
last if $success = something();
| [reply] [d/l] |
Re: Friday Code Quiz
by japhy (Canon) on Sep 21, 2001 at 16:59 UTC
|
I like this more: @list = 1, 2, 3, 4;
_____________________________________________________
Jeff[japhy]Pinyan:
Perl,
regex,
and perl
hacker.
s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??; | [reply] |
Re: Friday Code Quiz
by Zaxo (Archbishop) on Sep 21, 2001 at 15:43 UTC
|
| [reply] [d/l] |
Re (tilly) 1: Friday Code Quiz
by tilly (Archbishop) on Sep 21, 2001 at 15:59 UTC
|
I was a smartarse, and I can be even more of one because I
also knew that warnings will tell you that something
is up.
And to demonstrate that I am not just saying that I knew
it, I mentioned this quite a while ago. | [reply] |
Re: Friday Code Quiz
by ChOas (Curate) on Sep 21, 2001 at 15:23 UTC
|
Okay, a shot at it: it won`t be 1,2, as it`s not quoted;
It won`t be the last element of the a list as it`s not bracketed (sp.?) as a list;
Idea: Perl tries to parse 1,2 into a scalar, fails at the comma,
does the best to do the thing that seems logical and parses it as
$i=1,(as an int) truncating the ,2 to the semi-colon...
and skipping to the next instruction
But then again.. I should read a lot on the Perl parser...
GreetZ!,
print "profeth still\n" if /bird|devil/; | [reply] |
Re: Friday Code Quiz
by broquaint (Abbot) on Sep 21, 2001 at 15:41 UTC
|
I'm reckoning it's the comma operater, evaluating left to right and returning the last value evaluated (very handy in for loops in C). Or I could be wrong...
broquaint
Update: bah humbug running the code first! That's like looking at the answers in the back of the book then trying to explain why they work (unless of course you know ;o) | [reply] |
|
|
| [reply] |
Re: Friday Code Quiz
by lestrrat (Deacon) on Sep 21, 2001 at 22:44 UTC
|
| [reply] |