This should be run from a file.
#!perl -n @_=$_}BEGIN{eval'@{$_}=${@_}'for%::}{eval"@_"|| print "Just another perl hacker.\n"


Updated so as not to be wrong. Hence Dr Schodckwms reply below isn't as silly as it may seem.

Replies are listed 'Best First'.
Re: A simple JAPH
by jdalbec (Deacon) on Mar 10, 2005 at 03:25 UTC
    perl -MO=Deparse is more informative:
    LINE: while (defined($_ = <ARGV>)) { @_ = $_; } sub BEGIN { foreach $_ (%main::) { eval '@{$_}=${@_}'; } } { print "Just another perl hacker.\n" unless eval "@_"; }
    The message
    Can't locate Term/ReadLine.pm in @INC (@INC contains: )
    occurs because the BEGIN subroutine clobbers every global array variable including @INC. Clobbering @ARGV causes the while loop not to open any files (although as often as not I get the message Can't open : No such file or directory.). Clobbering @_ ensures that it evaluates as false so that JAPH will be printed.
      No, that is not how it works.
      Or at least not how it should, I don't get that can't open message, and indeed one should not get that.
      I'm using ActiveState 5.8.4, but this should not make a difference as the logic is sound (and more cunning than you have so far guessed).
        Hint: clobbered? or assigned?
        I'm using perl, v5.8.1-RC3 built for darwin-thread-multi-2level, and sometimes the variables do get clobbered (rather than assigned). The explanation you're looking for is that
        each array variable is assigned the value ${@_}. BEGIN is called with no arguments, so @_ is empty. ${@_} puts @_ in scalar context so @_ evaluates to the number of its elements, which is 0.

        So each array variable is being assigned the value of $0 which is the name of the source file. The while loop reads each line of the source file and sets @_ to the array consisting of that line. At the end of the loop @_ contains only the last line of the file, which evals to 1 and prints the JAPH message as a side effect. The second half of the || should never be executed.

        The problem with this explanation is that the order of the variables in %:: is not fixed. Once you set @_ to $0 it is no longer empty, so any subsequent assignments are taken from $1 which is undefined. I've extended your code to print the assignments it's making as they happen:
        LINE: while ( defined( $_ = <ARGV> ) ) { @_ = $_; } sub BEGIN { foreach $_ (%main::) { print "\@{$_}='${@_}'\n"; eval '@{$_}=${@_}'; } } { print "Just another perl hacker.\n" unless eval "@_"; }
        I realize this messes up your carefully-designed layout, but eval "}\n" seems to evaluate to a false value, so it still prints the JAPH message. Here's partial output from one less-successful run:
        @{STDIN}='dedalus.pl.tdy' @{*main::STDIN}='dedalus.pl.tdy' ... @{_}='dedalus.pl.tdy' @{*main::_}='' ... @{ARGV}='' @{*main::ARGV}='' ... Can't open : No such file or directory at dedalus.pl.tdy line 1. Just another perl hacker.
        The following modification of your code seems to work reliably here:
        #! /usr/bin/perl -n @_=$_}BEGIN{eval'@{$_}=${@_}'for sort keys%::}{eval"@_"|| print "Just another perl hacker.\n"
Re: A simple JAPH
by ww (Archbishop) on Mar 09, 2005 at 18:45 UTC

    ok; I confess: I'm pretty sure I'm not getting the point. Some kind and wise one wanta' elucidate?

    from nutshell

    " -n (c)auses Perl to assume the following loop around your script, which makes it iterate over filename arguments:"

    LINE:
    while (<>) {
    ... # your script goes here

    "By default, the lines are not printed. See -p to have lines printed. BEGIN and END blocks may be used to capture control before or after the implicit loop."

    and perl -d japh.pl produces (in relevant part):

    main::(japh.pl:4): print "Just another perl hacker." Can't locate Term/ReadLine.pm in @INC (@INC contains: ) at C:/Perl/lib +/perl5db.pl line 5725. Can't locate Term/ReadLine.pm in @INC (@INC contains: ) at C:/Perl/lib +/perl5db.pl line 5725. END failed--call queue aborted at japh.pl line 5725.

    Same result obtains, with OR without filename arguments.

    in cb, holli notes that removing -n produces an error...

    So... without digging into all 5725 (+?) lines of ReadLine.pm, I have the impression that the true secret is the lack of "-w" in the shebang or "use warnings" ???

      Nope.