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

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

Thread Previous | Thread Next
From:
Rafael Garcia-Suarez
Date:
August 24, 2008 06:42
Subject:
Re: [perl #57646] Weird non-equivalence between $::{'a'} = sub {} and *::a = sub {}
Message ID:
b77c1dce0808240642y5732b67dr68e007e85bbb1feb@mail.gmail.com
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.

Thread Previous | 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