linguistics, computers, and puns

Stupid Perl Tricks

Tim Hammerquist September 10, 2012 #perl

... wherein we demonstrate the wholesale assignment of an external package's symbol table to a lexical hash. We further demonstrate that bidirectional manipulation of the external package is possible.

In fact, the lexical scalar becomes a hashref to the symbol table itself...

use strict;

package Foo;

use vars qw/$bar $baz/;

$bar = "This is bar.";
$baz = "This is baz.";


package main;

# here's the money shot
my $stuff = \%Foo::;

# we can see they are raw symtable refs
print "\$stuff->{bar} => " . $stuff->{bar} . "\n";
print "\$stuff->{baz} => " . $stuff->{baz} . "\n";

# same data referenced via direct package and via imported refs
print "\$Foo::bar => $Foo::bar\n";
print "\$Foo::baz => $Foo::baz\n";
print "\${\$stuff->{bar}} => " . ${$stuff->{bar}} . "\n";
print "\${\$stuff->{baz}} => " . ${$stuff->{baz}} . "\n";

# create a scope for some ugly symtable magic
{
  # symtable magic only works for package vars, no lexicals
  # ergo, poke a hole for these vars
  use vars qw/ $bar2 $baz2 /;
  $bar2 = "This is no longer bar.";
  $baz2 = "STFU wesolows";

  # now the ugly part: symtable ref assignment
  no strict qw/refs/;
  *{$stuff->{bar}} = *bar2;
  *{$stuff->{baz}} = *baz2;
}

# ... et voilà!
print "\$Foo::bar => $Foo::bar\n";
print "\$Foo::baz => $Foo::baz\n";
print "\${\$stuff->{bar}} => " . ${$stuff->{bar}} . "\n";
print "\${\$stuff->{baz}} => " . ${$stuff->{baz}} . "\n";