Just tried this on london.pm and they seemed to quite enjoy it... so it's your turn now.

After running the following code what does $i contain - and explain your answer.

$i = 1,2;

It seems that people's answers go through three stages:

  1. Right answer for the wrong reason
  2. Wrong answer for the right(ish) reason
  3. Right answer for the right reason

Old hands seem to leap right in at stage two :) If you leap straight in at stage three then you can consider yourself a bit of a smartarse.

--
<http://www.dave.org.uk>

"The first rule of Perl club is you don't talk about Perl club."

Replies are listed 'Best First'.
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

      Spot on. Well done.

      It's the relative precedence of '=' and ',' that confuses most people.

      Update: Slight spoiler blackboxed.

      --
      <http://www.dave.org.uk>

      "The first rule of Perl club is you don't talk about Perl club."

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."

      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

      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();
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:??;

Re: Friday Code Quiz
by Zaxo (Archbishop) on Sep 21, 2001 at 15:43 UTC

    The comma here is the sequence operator. $i=1 is evaluated, then 2 is. 2 is the value of the whole statement. The construction $j=do{$i=1,2};gives $i value 1, and $j value 2.

    Update: spoiler blackboxed

    After Compline,
    Zaxo

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.

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!,
      ChOas

    print "profeth still\n" if /bird|devil/;
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)

      But the last value evaluated would be 2. And $i is set to 1.

      --
      <http://www.dave.org.uk>

      "The first rule of Perl club is you don't talk about Perl club."

Re: Friday Code Quiz
by lestrrat (Deacon) on Sep 21, 2001 at 22:44 UTC