in reply to Re: A simple JAPH
in thread A simple JAPH

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

Replies are listed 'Best First'.
Re^3: A simple JAPH
by Dedalus (Scribe) on Mar 10, 2005 at 22:10 UTC
    Hint: clobbered? or assigned?
Re^3: A simple JAPH
by jdalbec (Deacon) on Mar 11, 2005 at 04:06 UTC
    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"