Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

__PACKAGE__ symbol has wrong value after eval or require #7608

Closed
p5pRT opened this issue Nov 22, 2004 · 12 comments
Closed

__PACKAGE__ symbol has wrong value after eval or require #7608

p5pRT opened this issue Nov 22, 2004 · 12 comments

Comments

@p5pRT
Copy link

p5pRT commented Nov 22, 2004

Migrated from rt.perl.org#32562 (status was 'resolved')

Searchable as RT32562$

@p5pRT
Copy link
Author

p5pRT commented Nov 22, 2004

From @mjdominus

Created by @mjdominus

  perl -le 'package D; eval q{print __PACKAGE__}'

This prints "main", but it should print "D".

Similarly,

  perl -le 'package D; require "printpack.pl"'

does the same, when "printpack.pl" contains

  print __PACKAGE__;

This was reported to me by Benjamin Smith, bsmith@​cpan.org.
Jeff Goff and Randal Schwartz confirmed that it occurs in 5.8.5.

Note that variables and subroutines defined inside the "eval" or
inside of "printpack.pl" are in fact installed into the correct stash,
D; the only problem seems to be with the behavior of __PACKAGE__.

Perl Info

Flags:
    category=core
    severity=low

Site configuration information for perl v5.8.0:

Configured by mjd at Thu Apr 17 11:57:37 EDT 2003.

Summary of my perl5 (revision 5.0 version 8 subversion 0) configuration:
  Platform:
    osname=linux, osvers=2.4.2-2, archname=i586-linux
    uname='linux plover.com 2.4.2-2 #1 sun apr 8 19:37:14 edt 2001 i586 unknown '
    config_args='-des'
    hint=previous, useposix=true, d_sigaction=define
    usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef
    useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
    use64bitint=undef use64bitall=undef uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm',
    optimize='-O2',
    cppflags='-fno-strict-aliasing -I/usr/local/include -I/usr/include/gdbm -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm'
    ccversion='', gccversion='2.96 20000731 (Red Hat Linux 7.1 2.96-81)', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=4, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib
    libs=-lnsl -lndbm -lgdbm -ldl -lm -lc -lcrypt -lutil
    perllibs=-lnsl -ldl -lm -lc -lcrypt -lutil
    libc=/lib/libc-2.2.2.so, so=so, useshrplib=false, libperl=libperl.a
    gnulibc_version='2.2.4'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic'
    cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib'

Locally applied patches:
    


@INC for perl v5.8.0:
    /usr/local/lib/perl5/5.8.0/i586-linux
    /usr/local/lib/perl5/5.8.0
    /usr/local/lib/perl5/site_perl/5.8.0/i586-linux
    /usr/local/lib/perl5/site_perl/5.8.0
    /usr/local/lib/perl5/site_perl/5.7.3
    /usr/local/lib/perl5/site_perl/5.7.2
    /usr/local/lib/perl5/site_perl/5.6.1
    /usr/local/lib/perl5/site_perl/5.6.0
    /usr/local/lib/perl5/site_perl
    .


Environment for perl v5.8.0:
    HOME=/home/mjd
    LANG=C
    LANGUAGE (unset)
    LD_LIBRARY_PATH=/lib:/usr/lib:/usr/X11R6/lib
    LOGDIR (unset)
    PATH=/home/mjd/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/usr/games:/sbin:/usr/sbin:/usr/local/bin/X11R6:/usr/local/bin/mh:/data/mysql/bin:/usr/local/bin/pbm:/usr/local/bin/ezmlm:/home/mjd/TPI/bin:/usr/local/teTeX/bin:/usr/local/mysql/bin
    PERL_BADLANG (unset)
    SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Nov 23, 2004

From @rgs

Mark-Jason Dominus (via RT) wrote​:

    perl \-le 'package D; eval q\{print \_\_PACKAGE\_\_\}'

This prints "main", but it should print "D".

This very simple patch appears to fix it :

--- toke.c (revision 4047)
+++ toke.c (working copy)
@​@​ -4305,7 +4305,7 @​@​
  case KEY___PACKAGE__​:
  yylval.opval = (OP*)newSVOP(OP_CONST, 0,
  (PL_curstash
- ? newSVsv(PL_curstname)
+ ? newSVpv(HvNAME(PL_curstash), 0)
  : &PL_sv_undef));
  TERM(THING);

End.

Now, this might be only an indication of a deeper problem with PL_curstname,
which might not be correctly set everytime it should.

@p5pRT
Copy link
Author

p5pRT commented Nov 23, 2004

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Nov 23, 2004

From @steve-m-hay

Rafael Garcia-Suarez wrote​:

Mark-Jason Dominus (via RT) wrote​:

   perl \-le 'package D; eval q\{print \_\_PACKAGE\_\_\}'

This prints "main", but it should print "D".

This very simple patch appears to fix it :

It also seems to fix the similar bug reported a while back by Schwern
which wasn't solved at the time​:

http​://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2004-04/msg00433.html

- Steve


Radan Computational Ltd.

The information contained in this message and any files transmitted with it are confidential and intended for the addressee(s) only. If you have received this message in error or there are any problems, please notify the sender immediately. The unauthorized use, disclosure, copying or alteration of this message is strictly forbidden. Note that any views or opinions presented in this email are solely those of the author and do not necessarily represent those of Radan Computational Ltd. The recipient(s) of this message should check it and any attached files for viruses​: Radan Computational will accept no liability for any damage caused by any virus transmitted by this email.

@p5pRT
Copy link
Author

p5pRT commented Nov 23, 2004

From @rgs

Rafael Garcia-Suarez wrote​:

Mark-Jason Dominus (via RT) wrote​:

    perl \-le 'package D; eval q\{print \_\_PACKAGE\_\_\}'

This prints "main", but it should print "D".

This very simple patch appears to fix it :

--- toke.c (revision 4047)
+++ toke.c (working copy)
@​@​ -4305,7 +4305,7 @​@​
case KEY___PACKAGE__​:
yylval.opval = (OP*)newSVOP(OP_CONST, 0,
(PL_curstash
- ? newSVsv(PL_curstname)
+ ? newSVpv(HvNAME(PL_curstash), 0)
: &PL_sv_undef));
TERM(THING);

End.

Now, this might be only an indication of a deeper problem with PL_curstname,
which might not be correctly set everytime it should.

Yes, the following patch seems to be more logical, but it breaks lots of
regression tests in obscure ways :

--- pp_ctl.c (revision 4033)
+++ pp_ctl.c (working copy)
@​@​ -2917,7 +2917,9 @​@​

  if (CopSTASH_ne(PL_curcop, PL_curstash)) {
  SAVESPTR(PL_curstash);
+ SAVESPTR(PL_curstname);
  PL_curstash = CopSTASH(PL_curcop);
+ sv_setpv(PL_curstname, HvNAME(PL_curstash));
  }
  SAVESPTR(PL_beginav);
  PL_beginav = newAV();
End.

So I'm going to commit the first one, with tests.

--
A corpse is meat gone bad.
  -- Ulysses

@p5pRT
Copy link
Author

p5pRT commented Nov 23, 2004

From @rgs

Fixed by :
Change 23528 by rgs@​grubert on 2004/11/23 13​:35​:34

  Fix for bug​: [perl #32562] __PACKAGE__ symbol has wrong value
  after eval or require

@p5pRT
Copy link
Author

p5pRT commented Nov 23, 2004

@rgs - Status changed from 'open' to 'resolved'

@p5pRT p5pRT closed this as completed Nov 23, 2004
@p5pRT
Copy link
Author

p5pRT commented Nov 23, 2004

From @smpeters

[rafael - Tue Nov 23 06​:05​:10 2004]​:

Fixed by :
Change 23528 by rgs@​grubert on 2004/11/23 13​:35​:34

    Fix for bug​: \[perl \#32562\] \_\_PACKAGE\_\_ symbol has wrong value
    after eval or require

The follow patch for a test case works with change #23528 but fails with
previous bleads.

Inline Patch
--- t/op/my_stash.t.orig        Tue Nov 23 08:06:42 2004
+++ t/op/my_stash.t     Tue Nov 23 08:06:55 2004
@@ -31,3 +31,5 @@
     ok $@;
 #    print $@ if $@;
 }
+
+eval q{ok __PACKAGE__ eq 'Foo'};

@p5pRT
Copy link
Author

p5pRT commented Nov 23, 2004

From @rgs

Steve Peters via RT wrote​:

[rafael - Tue Nov 23 06​:05​:10 2004]​:

Fixed by :
Change 23528 by rgs@​grubert on 2004/11/23 13​:35​:34

    Fix for bug​: \[perl \#32562\] \_\_PACKAGE\_\_ symbol has wrong value
    after eval or require

The follow patch for a test case works with change #23528 but fails with
previous bleads.

Thanks, I've already commited a test like this one, in t/comp/package.t.
(t/op/my_stash.t tests the C<my Dog $spot> construct, so it's not
exactly the correct place for it :)

--- t/op/my_stash.t.orig Tue Nov 23 08​:06​:42 2004
+++ t/op/my_stash.t Tue Nov 23 08​:06​:55 2004
@​@​ -31,3 +31,5 @​@​
ok $@​;
# print $@​ if $@​;
}
+
+eval q{ok __PACKAGE__ eq 'Foo'};

@p5pRT
Copy link
Author

p5pRT commented Jan 3, 2005

From nick@ing-simmons.net

Rafael Garcia-Suarez <rgarciasuarez@​mandrakesoft.com> writes​:

Mark-Jason Dominus (via RT) wrote​:

    perl \-le 'package D; eval q\{print \_\_PACKAGE\_\_\}'

This prints "main", but it should print "D".

This very simple patch appears to fix it :

It may _change_ it, but is it a fix?
__PACKAGE__ reflects the current package of the lexical scope.
eval "" and require start a new scope.

--- toke.c (revision 4047)
+++ toke.c (working copy)
@​@​ -4305,7 +4305,7 @​@​
case KEY___PACKAGE__​:
yylval.opval = (OP*)newSVOP(OP_CONST, 0,
(PL_curstash
- ? newSVsv(PL_curstname)
+ ? newSVpv(HvNAME(PL_curstash), 0)
: &PL_sv_undef));
TERM(THING);

End.

Now, this might be only an indication of a deeper problem with PL_curstname,
which might not be correctly set everytime it should.

@p5pRT
Copy link
Author

p5pRT commented Jan 3, 2005

From @rgs

Nick Ing-Simmons wrote​:

Rafael Garcia-Suarez <rgarciasuarez@​mandrakesoft.com> writes​:

Mark-Jason Dominus (via RT) wrote​:

    perl \-le 'package D; eval q\{print \_\_PACKAGE\_\_\}'

This prints "main", but it should print "D".

This very simple patch appears to fix it :

It may _change_ it, but is it a fix?
__PACKAGE__ reflects the current package of the lexical scope.
eval "" and require start a new scope.

A new scope, yes, but a new namespace ?

Given that my patch changed the behaviour of require'ing a file which
doesn't contain a package declaration, I'm happy to discuss this; but
the previous behaviour wasn't documented nor tested, and seems
surprising to me.

--
--Silence! What opera resembles a railwayline? Reflect, ponder,
  excogitate, reply.
  -- Ulysses

@p5pRT
Copy link
Author

p5pRT commented Jan 3, 2005

From nick@ing-simmons.net

Rafael Garcia-Suarez <rgarciasuarez@​mandrakesoft.com> writes​:

Nick Ing-Simmons wrote​:

Rafael Garcia-Suarez <rgarciasuarez@​mandrakesoft.com> writes​:

Mark-Jason Dominus (via RT) wrote​:

    perl \-le 'package D; eval q\{print \_\_PACKAGE\_\_\}'

This prints "main", but it should print "D".

This very simple patch appears to fix it :

It may _change_ it, but is it a fix?
__PACKAGE__ reflects the current package of the lexical scope.
eval "" and require start a new scope.

A new scope, yes, but a new namespace ?

Given that my patch changed the behaviour of require'ing a file which
doesn't contain a package declaration, I'm happy to discuss this;

Does it affect 'do' as well?

but
the previous behaviour wasn't documented nor tested, and seems
surprising to me.

It surprised me once, not that I was using it, but that
various things that eval/required had to have package added
before they did what I wanted.
e.g. autosplit etc.

I suspect that behaviour was useful for perl4-ish .pl files
it may no longer matter...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant