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

Weird non-equivalence between $::{'a'} = sub {} and *::a = sub {} #9441

Closed
p5pRT opened this issue Aug 6, 2008 · 6 comments
Closed

Weird non-equivalence between $::{'a'} = sub {} and *::a = sub {} #9441

p5pRT opened this issue Aug 6, 2008 · 6 comments

Comments

@p5pRT
Copy link

p5pRT commented Aug 6, 2008

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

Searchable as RT57646$

@p5pRT
Copy link
Author

p5pRT commented Aug 6, 2008

From @Drahflow

-----BEGIN PGP SIGNED MESSAGE-----
Hash​: SHA1

Testcase​:

#/usr/bin/perl

use Carp;
use strict;
use warnings;

$​::{'a'} = sub { print "a\n"; };
$​::{'b'} = sub { print "b\n"; };
# *​::a = sub { print "a\n"; };
# *​::b = sub { print "b\n"; };

a();

eval "a()"; confess $@​ if $@​;
eval "b()"; confess $@​ if $@​;

Output​:

a
a
Undefined subroutine &main​::b called at (eval 2) line 1.
at test.pl line 15

Plain English Version​:

Something odd is happening if a sub reference is assigned to a
symbol table entry. In particular, the behaviour is different
from the behaviour encountered if said assignment goes through
the typeglob. This can easily be checked, if the commented lines
are put in, and the other assignments commented out.

Also the oddness can be modified by calling the sub directly
somewhere else, presumably because this will create or change
the respective symbol table entry.

This difference might seem totally insignificant. If the names
"a" and "b" are supplied dynamically however, the non-working
version is IMHO superior (apart from its non-working), because
there will be no need for an eval, and neither one for symbolic
de-referencing.

The documentation in "perlmod" seems to imply that the typeglob
and the symbol table entry are one and the same, so if this is
considered correct behaviour, maybe the docs should be mended.

Best Regards,
  Jens-W. Schicke

perlbug -d​:

- ---
Flags​:
  category=
  severity=
- ---
Site configuration information for perl v5.8.8​:

Configured by Debian Project at Mon Nov 12 17​:04​:39 UTC 2007.

Summary of my perl5 (revision 5 version 8 subversion 8) configuration​:
  Platform​:
  osname=linux, osvers=2.6.17-2-vserver-amd64, archname=x86_64-linux-gnu-thread-multi
  uname='linux excelsior 2.6.17-2-vserver-amd64 #1 smp wed sep 13 18​:02​:36 cest 2006 x86_64 gnulinux '
  config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN -Dcccdlflags=-fPIC -Darchname=x86_64-linux-gnu -Dprefix=/usr -Dprivlib=/usr/share/perl/5.8 -Darchlib=/usr/lib/perl/5.8 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.8.8 -Dsitearch=/usr/local/lib/perl/5.8.8 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Ud_ualarm -Uusesfio -Uusenm -Duseshrplib -Dlibperl=libperl.so.5.8.8 -Dd_dosuid -des'
  hint=recommended, useposix=true, d_sigaction=define
  usethreads=define use5005threads=undef useithreads=define usemultiplicity=define
  useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
  use64bitint=define use64bitall=define uselongdouble=undef
  usemymalloc=n, bincompat5005=undef
  Compiler​:
  cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
  optimize='-O2',
  cppflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include'
  ccversion='', gccversion='4.2.3 20071014 (prerelease) (Debian 4.2.2-3)', gccosandvers=''
  intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
  d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
  ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
  alignbytes=8, prototype=define
  Linker and Libraries​:
  ld='cc', ldflags =' -L/usr/local/lib'
  libpth=/usr/local/lib /lib /usr/lib
  libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt
  perllibs=-ldl -lm -lpthread -lc -lcrypt
  libc=/lib/libc-2.6.1.so, so=so, useshrplib=true, libperl=libperl.so.5.8.8
  gnulibc_version='2.6.1'
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
  cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib'

Locally applied patches​:

- ---
@​INC for perl v5.8.8​:
  /etc/perl
  /usr/local/lib/perl/5.8.8
  /usr/local/share/perl/5.8.8
  /usr/lib/perl5
  /usr/share/perl5
  /usr/lib/perl/5.8
  /usr/share/perl/5.8
  /usr/local/lib/site_perl
  .

- ---
Environment for perl v5.8.8​:
  HOME=/home/drahflow
  LANG (unset)
  LANGUAGE (unset)
  LD_LIBRARY_PATH (unset)
  LOGDIR (unset)
  PATH=/usr/local/bin​:/usr/bin​:/bin​:/usr/games
  PERL_BADLANG (unset)
  SHELL=/bin/zsh
-----BEGIN PGP SIGNATURE-----
Version​: GnuPG v1.4.6 (GNU/Linux)

iD8DBQFImVcOzhchXT4RR5ARArUwAKDZzuE4SYWfkzAjnzvBJoqpUsqFmQCgiEpX
3xRjouV+b+vY+QMxMDsEQ9s=
=gnF2
-----END PGP SIGNATURE-----

@p5pRT
Copy link
Author

p5pRT commented Aug 6, 2008

From p5p@spam.wizbit.be

On Wed Aug 06 00​:47​:57 2008, drahflow@​gmx.de wrote​:

-----BEGIN PGP SIGNED MESSAGE-----
Hash​: SHA1

Testcase​:

#/usr/bin/perl

use Carp;
use strict;
use warnings;

$​::{'a'} = sub { print "a\n"; };
$​::{'b'} = sub { print "b\n"; };
# *​::a = sub { print "a\n"; };
# *​::b = sub { print "b\n"; };

a();

eval "a()"; confess $@​ if $@​;
eval "b()"; confess $@​ if $@​;

Output​:

a
a
Undefined subroutine &main​::b called at (eval 2) line 1.
at test.pl line 15

Plain English Version​:

Something odd is happening if a sub reference is assigned to a
symbol table entry. In particular, the behaviour is different
from the behaviour encountered if said assignment goes through
the typeglob. This can easily be checked, if the commented lines
are put in, and the other assignments commented out.

Also the oddness can be modified by calling the sub directly
somewhere else, presumably because this will create or change
the respective symbol table entry.

This difference might seem totally insignificant. If the names
"a" and "b" are supplied dynamically however, the non-working
version is IMHO superior (apart from its non-working), because
there will be no need for an eval, and neither one for symbolic
de-referencing.

The documentation in "perlmod" seems to imply that the typeglob
and the symbol table entry are one and the same, so if this is
considered correct behaviour, maybe the docs should be mended.

Best Regards,
Jens-W. Schicke

Easier examples​:

$ perl -le '$main​::{foo} = \"a"; eval "print \$foo;";'
(no output - a was 'expected')

$ perl -wle '$main​::{foo} = \"a"; eval "print \$foo;";$_=$foo;'
Name "main​::foo" used only once​: possible typo at -e line 1.
a

$ perl -wle '*foo = \"a"; eval "print \$foo;";'
Name "main​::foo" used only once​: possible typo at -e line 1.
a

Another example​:

$ cat rt-57646.pl
print $main​::foo;

$ perl -wle '$main​::{foo} = \"a"; require "rt-57646.pl";'
Use of uninitialized value in print at rt-57646.pl line 1.

('a' was 'exepected' instead of undef)

$ perl -wle '$main​::{foo} = \"a"; require "rt-57646.pl";$_=$foo;'
Name "main​::foo" used only once​: possible typo at -e line 1.
a

This behaviour goes back to at least 5.00504.

I vote to remove the line​:
  local $main​::{foo} = $main​::{bar};
from the documentation in perlmod.

It seems to me that explaining that it needs a reference to *foo which
is known at compile time is going to be more confusing then simple
removing it. (Unless someone wants to take a try at fixing this
behavoiur?)

Patch that removes the text is attached.

Kind regards,

Bram

@p5pRT
Copy link
Author

p5pRT commented Aug 6, 2008

@p5pRT
Copy link
Author

p5pRT commented Aug 6, 2008

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

@p5pRT
Copy link
Author

p5pRT commented Aug 24, 2008

From @rgs

2008/8/6 Bram via RT <perlbug-followup@​perl.org>​:

On Wed Aug 06 00​:47​:57 2008, drahflow@​gmx.de wrote​:

-----BEGIN PGP SIGNED MESSAGE-----
Hash​: SHA1

Testcase​:

#/usr/bin/perl

use Carp;
use strict;
use warnings;

$​::{'a'} = sub { print "a\n"; };
$​::{'b'} = sub { print "b\n"; };
# *​::a = sub { print "a\n"; };
# *​::b = sub { print "b\n"; };

a();

eval "a()"; confess $@​ if $@​;
eval "b()"; confess $@​ if $@​;

Output​:

a
a
Undefined subroutine &main​::b called at (eval 2) line 1.
at test.pl line 15

Plain English Version​:

Something odd is happening if a sub reference is assigned to a
symbol table entry. In particular, the behaviour is different
from the behaviour encountered if said assignment goes through
the typeglob. This can easily be checked, if the commented lines
are put in, and the other assignments commented out.

Also the oddness can be modified by calling the sub directly
somewhere else, presumably because this will create or change
the respective symbol table entry.

This difference might seem totally insignificant. If the names
"a" and "b" are supplied dynamically however, the non-working
version is IMHO superior (apart from its non-working), because
there will be no need for an eval, and neither one for symbolic
de-referencing.

The documentation in "perlmod" seems to imply that the typeglob
and the symbol table entry are one and the same, so if this is
considered correct behaviour, maybe the docs should be mended.

Best Regards,
Jens-W. Schicke

Easier examples​:

$ perl -le '$main​::{foo} = \"a"; eval "print \$foo;";'
(no output - a was 'expected')

$ perl -wle '$main​::{foo} = \"a"; eval "print \$foo;";$_=$foo;'
Name "main​::foo" used only once​: possible typo at -e line 1.
a

$ perl -wle '*foo = \"a"; eval "print \$foo;";'
Name "main​::foo" used only once​: possible typo at -e line 1.
a

Another example​:

$ cat rt-57646.pl
print $main​::foo;

$ perl -wle '$main​::{foo} = \"a"; require "rt-57646.pl";'
Use of uninitialized value in print at rt-57646.pl line 1.

('a' was 'exepected' instead of undef)

$ perl -wle '$main​::{foo} = \"a"; require "rt-57646.pl";$_=$foo;'
Name "main​::foo" used only once​: possible typo at -e line 1.
a

This behaviour goes back to at least 5.00504.

I vote to remove the line​:
local $main​::{foo} = $main​::{bar};
from the documentation in perlmod.

It seems to me that explaining that it needs a reference to *foo which
is known at compile time is going to be more confusing then simple
removing it. (Unless someone wants to take a try at fixing this
behavoiur?)

Patch that removes the text is attached.

Thanks, applied as #34221.

@p5pRT
Copy link
Author

p5pRT commented Aug 24, 2008

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

@p5pRT p5pRT closed this as completed Aug 24, 2008
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant