http://www.perlmonks.org?node_id=87335

I was inspired me to write a follow up on Nysus's series of brain teasers. So here it goes:

Here's the code:

print \\///\\\//;
Questions:
  • Why does it parse and what does it mean
  • Why does it evaluate to zero

    Now, if you need a hint, look at the bottom of this node. If these aren't answered by tommorow, I'll post the answers.

    The 15 year old, freshman programmer,
    Stephen Rawls

  • Replies are listed 'Best First'.
    Re: Brain Teaser
    by tachyon (Chancellor) on Jun 10, 2001 at 23:55 UTC

      Excellent teaser. It parses because it is legal perl syntax of course! In this context it means print a reference to a reference to the return value of m// divided by a reference to a reference to a reference to the return value of m//. Wow that's a mouthful. In code form:

      print //; # prints 1, scalar return val of match null in $_ (alw +ays true) print \//; # SCALAR(0x....) print \\//; # ditto print \\\//; # ditto print \\\\//; # ditto etc... # thus what you are saying is divide the scalar value # of one memory reference by another print \\// / \\\// ref div ref

      It does not evaluate to 0 however as you imply. I get 0.999998046573592 on Win32 as we are dividing two closely allied memory addresses by each other. The first one evaled logically gets the smaller memory address (stack theory) so the result should always be a number just less than 1 - the bigger the memory you have (and the closer to out of memory you are) the closer to one it will be. You can demonstrate my theory with this snippet

      $a = \1; # first ref in lower mem $b = \1; # second ref in slightly higher mem print $b/$a; # prints 1.00000684833673

      tachyon

        It does not evaluate to 0 however as you imply

        That is true; I simply made a mistake when I posted--I meant to say that it evaluates to 0 in integer cotext as in $a[//\\\///\\]. Good explanation though, and sorry about the slip : )

        The 15 year old, freshman programmer,
        Stephen Rawls

    Re: Brain Teaser
    by marcink (Monk) on Jun 10, 2001 at 22:59 UTC
      Update: added <READMORE> to let others have fun too ;-)
        Good job. You even got it after I forgot to write that it only returns 0 in integer context. In normal numeric context it returns something close to .9893410001 depending on your platform and whether or not you call the script from the command line with -e(the command line uses a different memory location).

        The 15 year old, freshman programmer,
        Stephen Rawls

          I looked at the above answer and I'm still not sure why it parses the way it does! Interesting.

          $PM = "Perl Monk's";
          $MCF = "Most Clueless Friar";
          $nysus = $PM . $MCF;

    Re: Brain Teaser
    by Abigail (Deacon) on Jun 11, 2001 at 00:19 UTC
      It evaluates to 0 (or rather, false) only if the print fails - otherwise, it will evaluate to true (1 in practise). ;-)

      perl -e '* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / + / / % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % + %; BEGIN {% % = ($ _ = " " => print "Just Another Perl Hacker\n" +)}'

      -- Abigail

        Tricky Abigail, but I meant what does \\///\\\// evaluate to (not print)--mabey I should have explained myself better. And again, that was a slip, I meant to say that it evaluates to 0 in integer context, in numeric context it evaluates to just under 1.

        The 15 year old, freshman programmer,
        Stephen Rawls

          Eh, perhaps on *your* system, but look at this:
          $ perl -le 'print \\///\\\//' 1.00000026558336981

          What the result of \\///\\\// is depends on how memory is alloced. It'll depend on your malloc (which could be the Perl supplied, or the system one, depending on how Perl was build); it'll hand out addresses using some algorithm, based on various factors. Don't assume that when you run it once on your system, it will be the same universally.

          -- Abigail