develooper Front page | perl.perl5.porters | Postings from August 2008

[perl #57646] Weird non-equivalence between $::{'a'} = sub {} and *::a = sub {}

Thread Next
From:
Bram via RT
Date:
August 6, 2008 04:57
Subject:
[perl #57646] Weird non-equivalence between $::{'a'} = sub {} and *::a = sub {}
Message ID:
rt-3.6.HEAD-29759-1218011060-645.57646-15-0@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.


Kind regards,

Bram

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About