develooper Front page | perl.perl5.porters | Postings from October 2003

Re: [perl #24139] Symbol Table entry always return defined for {SCALAR}!!!

Thread Previous | Thread Next
From:
Yitzchak Scott-Thoennes
Date:
October 7, 2003 03:39
Subject:
Re: [perl #24139] Symbol Table entry always return defined for {SCALAR}!!!
Message ID:
20031007103915.GA3256@efn.org
On Tue, Oct 07, 2003 at 04:48:44AM -0000, "Graciliano M. P." <perlbug-followup@perl.org> wrote:
> Why when you access the {SCALAR} key of a symbol entry in the Symbol Table
> of a package it always return a scalar reference?! Even if the scalar, or
> any symbol (array, hash, glob) with this name is not defined!
> For example:
>   my $name = 'main::test' ;
> 
>   if (defined *{$name}{SCALAR}) { print "\$$name\n" ;}
>   if (defined *{$name}{ARRAY}) { print "\@$name\n" ;}
>   if (defined *{$name}{HASH}) { print "\%$name\n" ;}
> 
> This prints:
> $main::test
> 
> If you set the array and hash before
>   @test = %test = 1 ;
> 
> it prints:
>   $main::test
>   @main::test
>   %main::test
> 
> Soo, it always print true for $main::test!!!
> The worst thing is that it always return a scalar reference:
>   my $name = 'main::test' ;
> 
>   my $ref = *{$name}{SCALAR} ;
>   print "$ref\n" ;
> 
> This prints:
>   SCALAR(0x1a6f080)
> 
> Soo, it always create a new scalar in the memory, even if you just want to
> know if the scalar exists in the memory!
> This was tested with Perl-5.6.1-Win32, Perl-5.8.1-Win32 (the new release),
> Perl-5.6.1-Linux.

Yes, currently (just about) whenever a glob exists, it will have a
scalar, whether used or not.  And saying *{$name}{WHATEVER} has a side
effect of creating the glob *$name.

> We can see that Devel::Symdump uses
> if (defined $val && defined *ENTRY{SCALAR}) {

There is no bug there.  It will only reach that code once it knows
there is an *ENTRY glob.  And if there is an *ENTRY glob, there will
be a scalar.  (It doesn't seem to know about FORMAT or sub
declarations, though.)

> I think that the behavior doesn't work like it should, since for {ARRAY} and
> {HASH} it works like we want. At least this need to be documented!

I think it is.  What exactly are you trying to do?  Maybe someone can give
you some help once we know?

You can check if a glob *foo::bar exists with something like:
if ( exists($foo::{bar}) && \$foo::{bar} eq 'GLOB' )

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