Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options

eval('__PACKAGE__') is always main?!!!

by gmpassos (Priest)
on Dec 23, 2004 at 19:19 UTC ( [id://417192] : perlquestion . print w/replies, xml ) Need Help??

gmpassos has asked for the wisdom of the Perl Monks concerning the following question:

Is that right?
package foo ; print eval('__PACKAGE__');
The sense tell me that should be foo! I tested this on Perl 5.6.1 and 5.8.3 and the output is the same.

Is that a bug or an odd behavior?

UP: Note that the main idea is not how to get foo as value. The idea is that __PACKAGE__ will always point to main unless we define the package inside the eval like this: eval('package foo ; __PACKAGE__'). This is very odd, since any code evaluated will make references to the local pakcage and not main.

Graciliano M. P.
"Creativity is the expression of liberty".

Replies are listed 'Best First'.
Re: eval('__PACKAGE__') is always main?!!!
by ikegami (Patriarch) on Dec 23, 2004 at 21:09 UTC

    The docs say "In the first form," eval EXPR, "the return value of EXPR is parsed and executed as if it were a little Perl program."

    Perl programs are put into main until a package statement is encountered, so the documentation is consistent with the behaviour (although an explicit statement about this behaviour would be favourable).

    Which means the following is wrong?

    sub moo { print("moooooain\n"); } package cow; sub moo { print("moooOoooOOoooo\n"); } # <--- prints this eval 'moo();';

    There's definitely a bug, since __PACKAGE__ does not agree with the function getting called.

    do EXPR is consistent with eval EXPR, as stated in do's docs:

    > echo "print(__PACKAGE__, $/);" > > perl -e "package foo; do '';" main

    Of course, eval EXPR is inconsistent with eval BLOCK which "parsed--and executed within the context of the current Perl program".

      (Following up on a brief CB /msg exchange, that may be interesting to other monks.)

      Speaking of documentation only here: I thought "executed within the context of the current Perl program" ought to have trumped eval EXPR's move to main, but as ikegami notes, the statement about context applies only to eval BLOCK.

      But eval BLOCK of course does share some (a lot of) state with the main program; there's no new perl interpreter constructed, and the following does change the value of $x in the main program:

      perl -le '$x = 42; eval q($x = 6*9); print $x'    # prints "54"

      The first thing that needs fixing in this case appears to be the docs.

Re: eval('__PACKAGE__') is always main?!!!
by MarkusLaker (Beadle) on Dec 23, 2004 at 20:13 UTC
    To this humble initiate, it looks like a bug. In the following test program, the text inside the eval seems (correctly) to run in package P; the only difference that prepending 'package P' makes is to set __PACKAGE__ correctly.


Re: eval('__PACKAGE__') is always main?!!!
by Anonymous Monk on Dec 24, 2004 at 00:18 UTC
Re: eval('__PACKAGE__') is always main?!!!
by gaal (Parson) on Dec 23, 2004 at 20:09 UTC
    If that happened, I would call it a bug. But for me, it doesn't happen:

    [roo@sike:~ 747] > perl -le 'package foo ;print eval('__PACKAGE__');' foo
    (This is perl, v5.8.4 built for i386-linux-thread-multi. Debian.)

      You made a classic shell quoting error - use double quotes for the internal quotes:

      perl -le 'package foo ;print eval("__PACKAGE__");'

      or, when your shell only gives you one flavour of quote, use Perls superior quoting facilities:

      perl -le 'package foo ;print eval(q(__PACKAGE__));'
        Eek, you're right; the unquoted __PACKAGE__ of course comes from the un-evaled compile-time pass, and hence does say "foo".

        I can't find mention of this behavior in the docs (eval is where I'd like it to be), so yes, I'd consider this a bug.

Re: eval('__PACKAGE__') is always main?!!!
by hossman (Prior) on Dec 23, 2004 at 20:14 UTC

    this is odd...

    hal:~> cat package foo ; print eval('__PACKAGE__'); hal:~> perl -l main hal:~> perl -le 'package foo ;print eval('__PACKAGE__');' foo

    Update: d'oh! ... that's what i get for trusting someone else's test case without looking at it closely.

    what makes the -e version "work" is definitely the quotes, perl is seeing it as...

    package foo ;print eval(__PACKAGE__); which case the __PACKAGE__ gets interpolated before the eval.