This is not really a JAPH, but still I think it's a witty use of some non-completely obvious code. Oh, and of course it may still puzzle the non-initiated:
# This prints: Just another Perl hacker, seek DATA,15,0 and print q... <DATA>; __END__

Replies are listed 'Best First'.
Re: Fake JAPH
by lithron (Chaplain) on Dec 10, 2004 at 23:34 UTC
    Okay, I'll take a whack at understanding this one. The seek statement looks through the __DATA__, which seems to be the whole script itself, by default. So it seeks 15 characters in, which puts it on the first line, just after the : and the space.

    Since the seek does not fail, then the print statement takes effect. "q... <DATA>" is equivilant of "q// . <DATA>". I'm guessing here in saying that the only reason the q// exists is so you can use <DATA> in a string context, and print it.

    Correct? Wrong? Other things I may have missed?

      Good job lithron!

      __END__ is the same as __DATA__ in a top level script. Any thing after __DATA__ can be read using the package name in conjunction with the DATA filehandle (PACKAGE::DATA). Since we're dealing with a top level script, main is the package and can be omitted.

      Seek is being called using the DATA filehandle, position of 15 (16th byte since it's zero based) and a whence of 0 (meaning set a new position).

      The seek succeeds so the print is then executed. q... <DATA> is equivilant to '' . <DATA>. This puts the read line from the DATA filehandle in scalar context which results in only one line being read. Had the q... been omitted, the entire script (starting at the 16th byte) would have been printed instead.

      Fundamentally correct: Mr. Muskrat already pinpointed some details. What I'd like to stress is that in Perl (5, that is!) there's hardly anything like a *string* context: C<q...> is an (hopefully somewhat cryptic) alternative to scalar().

      Had I not put it in, <DATA> would have been in list context, thus returning a list of all the lines of that FH. In which case I may have used

      # This prints: Just another Perl hacker, seek DATA,15,0 and print +(<DATA>)[0];
      instead, which is not just as nice IMHO...
        What I'd like to stress is that in Perl (5, that is!) there's hardly anything like a *string* context

        Actually, there is, and lots and lots of it. Perl could not do automatical transformation between numerical values and string values if it wasn't for string context:

        #!/usr/bin/perl use strict; use warnings; use Devel::Peek; my $var = 13; Dump($var); print "\n\n"; my $dummy = q...$var; Dump($var); __END__ SV = IV(0x8194b2c) at 0x8193d70 REFCNT = 1 FLAGS = (PADBUSY,PADMY,IOK,pIOK) IV = 13 SV = PVIV(0x8184448) at 0x8193d70 REFCNT = 1 FLAGS = (PADBUSY,PADMY,IOK,POK,pIOK,pPOK) IV = 13 PV = 0x818bca0 "13"\0 CUR = 2 LEN = 3
        As you can see, the use of $var in string context caused the upgrade from an IV to a PVIV.

        String context is also what triggers the stringify overload in objects (if defined).

Re: Fake JAPH
by PhilHibbs (Hermit) on Dec 16, 2004 at 09:07 UTC
    It doesn't seem to do anything on Win32 ActiveState Perl v5.8.1

    Ah, it does if I save it as a file, but not if the program is pasted in.

      Of course it needs to be saved as a file: it uses the DATA fh...