2

I tried delete the name of a package variable from the main:: symbol table as below, but seems later code could still reference the variable, why it can be referenced after deletion? What's the effect of removing a name from symbol table?

$n = 10;
delete $main::{'n'};
print $n;
Thomson
  • 20,586
  • 28
  • 90
  • 134
  • It seems like you want to remove/undef slots from typeglob; `perl -MData::Dumper -we '@n = 1..3; $n = 10; undef *n; print Dumper \@n, $n'` – mpapec Jan 29 '15 at 06:53
  • @Сухой27 Could you show some more details about the difference between remove the symbol and remove/undef slots from typeglob? – Thomson Jan 29 '15 at 07:10
  • `*n` is package typeglob holding slots for `$n, @n, %n, &n`. AFAIK `delete $main::{'n'}` deletes typeglob from package but slots can still be accessed as @ysth pointed out. – mpapec Jan 29 '15 at 07:40

1 Answers1

5

When perl code is compiled, globs for package variables/symbols are looked up (and created as necessary) and referenced directly from the compiled code.

So if you delete a symbol table entry $pkg::{n}, all the already compiled code that used $pkg::n, @pkg::n, etc., still use the original glob. But do/require'd code or eval STRING or symbolic references won't.

This code ends up with two *n globs; all the code compiled before the delete executes will reference the original one; all the code compiled after will reference the new one (and symbolic references will get whichever is in the symbol table at that point in runtime).

$n = 123;
delete $::{n};
eval '$n=456';
print $n;
eval 'print $n';

Another example:

$n = 123;
sub get_n { $n }
BEGIN { delete $::{n} }
$n = 456;
print get_n();
print $n;
ysth
  • 96,171
  • 6
  • 121
  • 214