in reply to deleting glob does not undef values?

$A::{bbb} is not what you think it is:
$A::{bbb} = 3; print $A::bbb; __END__

Nothing. And

$A::{bbb} = 3; $A::bbb = 4; __END__ Modification of a read-only value attempted at - line 2.

Huh?

$A::bbb = 3; $A::{bbb} = 4; print "$_ => $A::{$_}\n" for keys %A::; print $A::bbb,"\n"; __END__ bbb => *main::4

What's happening here? The %A:: has typeglobs as values, so assigning $A::{bbb} = 4 makes the literal 4 into a typeglob of the symbol table %main::. There's the glob, the typeglob entry in the symbol table, and the value in the glob's slot:

$A::bbb = 3; print $A::{bbb},"\n"; print *A::bbb{SCALAR},"\n"; print ${*A::bbb{SCALAR}},"\n"; __END__ *A::bbb SCALAR(0xa011750) 3

The special hash %A:: holds references to the typeglobs , these entries aren't the typeglobs themselves. but by deleting those entries you don't delete the glob. You mangle the lookup table only. their reference count must not go to zero. Since - as per your example - there's $A::bbb still present in compiled code, its reference count doesn't go to zero. So it is still accessible.

update: corrected above paragraph as per ysth's comment below. Thanks, ysth!

--shmem

_($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                              /\_¯/(q    /
----------------------------  \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

Replies are listed 'Best First'.
Re^2: deleting glob does not undef values?
by ysth (Canon) on Nov 22, 2007 at 16:50 UTC
    The special hash %A:: holds references to the typeglobs, these entries aren't the typeglobs themselves.
    No, they are the typeglobs themselves (or other things in some special cases, which means extreme care must be taken when directly accessing a symbol table). But globs are looked up and pointers to them inserted into code that uses variables of that name at compile time. delete does remove the glob from the symbol table hash, but the glob isn't freed if it is referenced by compiled code; any code compiled thereafter will create and reference a new glob, though.

    You can see this in action:

    $ perl -wle'use Devel::Peek "SvREFCNT"; $A = "foo"; BEGIN { print SvRE +FCNT($::{A}) } $A = "bar"; BEGIN { print SvREFCNT($::{A}) } delete $: +:{A}; eval "\$A = 1; print SvREFCNT(\$::{A})"' 2 3 2
    (One refcnt is held by the symbol table; additional ones are added for each reference in the code. The delete removes the glob from the symbol table, but it isn't freed since it still has 2 references.)