gmpassos has asked for the wisdom of the Perl Monks concerning the following question:

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.

We can see that Devel::Symdump uses

if (defined $val && defined *ENTRY{SCALAR}) {
to test if a scalar exists. But if the value of the scalar is undef it's says that the scalar is not in the table. And since *ENTRY{SCALAR} always return a scalar ref it's not needed.

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!

Graciliano M. P.
"Creativity is the expression of the liberty".

Replies are listed 'Best First'.
Re: Symbol Table entry always return defined for {SCALAR}!!!
by liz (Monsignor) on Oct 07, 2003 at 09:07 UTC
    This appears to be documented in perlref according to Steve Grazzini on p5p:
    *foo{THING} returns undef if that particular THING hasn't been used yet, except in the case of scalars. *foo{SCALAR} returns a reference to an anonymous scalar if $foo hasn't been used yet. This might change in a future release.

    This implies to me it might get changed for 5.10. But I certainly wouldn't count on it. And I certainly would not expect a bug fix for 5.8.2 soon.

    Liz

      What happens in more detail is that *foo{SCALAR} first looks up the glob *foo, creating it if it doesn't exist. And, for hysterical raisins, just about every glob has a scalar entry automatically created. Then it looks up the SCALAR entry for the glob, and what do you know, there it is. The automatic creation of scalars for every glob has been there a *long* time...I think people are a little scared to change it.
Re: Symbol Table entry always return defined for {SCALAR}!!!
by pg (Canon) on Oct 07, 2003 at 19:20 UTC

    You can actually make the sample code more clear, with absolutely no variables defined:

    if (defined *{'main::test'}{SCALAR}) { print "scalar" ;} if (defined *{'main::test'}{ARRAY}) { print "array" ;} if (defined *{'main::test'}{HASH}) { print "hash" ;}
    This still gives you scalar.

    However once you use 'use strict' to disallow symbolic ref, this code throws error. I assume most of the people use 'use strict' all the time, so the failure of this testing is not really that scary.

    On the other hand, to some level, it makes sense for this test to be successful for scalar, but not array and hash, as Perl subconsciously take a variable as scalar until it 'knows'.

      I put the name of the symbol inside an another scalar to explicity do not create the symbol in the table!

      For example, if you have

      package main ; print "$foo" ;
      you will have in the Symbol Table of main an entry for $foo (actually *foo), since the $foo in the print point to a s