On May 17, Paul Johnson said:
>You can't. You are trying to use symbolic references and when you have
>strict turned on you are promising not to do that.
>my $varname = "myvar";
>{
> no strict "refs";
> no strict "vars";
> @$varname = ('a','b','c');
>}
It's important to know one thing:
SYMBOLIC REFERENCES are means of getting to package variables!
As shown by this demonstration:
my $foo = "bar";
$main::foo = "BAR";
my $name = "foo";
print $$name; # prints 'BAR'
Now, as we all know (chances are a lot of us don't know), package
variables are different from my() variables because package variables
exist in something called the "symbol table". This is a hash, pretty much
like any other hash, that Perl uses to keep track of variables in every
package.
package Example;
$foo = 2;
@bar = (5,3,1);
%blat = (hello => 'world');
sub blat { print "hey HEY!" }
for my $symbol (sort keys %Example::) {
print " \$$symbol defined\n" if defined $$symbol;
print " \@$symbol defined\n" if defined @$symbol;
print " \%$symbol defined\n" if defined %$symbol;
print " \&$symbol defined\n" if defined &$symbol;
}
That tells me:
@bar defined
%blat defined
&blat defined
$foo defined
Pretty nifty, eh? But this doesn't run under 'strict refs', since $symbol
is a string (they're just keys in a hash, and keys in hashes are simple
strings). So how can we get this to work under strict, without turning it
off for our evil purposes?
By *using* the symbol table. Not just looking at it, but extracting
content from it.
Watch:
package Example;
$foo = 2;
@bar = (5,3,1);
%blat = (hello => 'world');
sub blat { print "hey HEY!" }
use strict;
for my $symbol (sort keys %Example::) {
print " \$$symbol defined\n" if defined ${ $Example::{$symbol} };
print " \@$symbol defined\n" if defined @{ $Example::{$symbol} };
print " \%$symbol defined\n" if defined %{ $Example::{$symbol} };
print " \&$symbol defined\n" if defined &{ $Example::{$symbol} };
}
First, you'll notice I waited to 'use strict' until after the variable
declarations. I could have done 'use vars qw( $foo @bar %blat )', but I
decided to be lazy.
Second, you'll notice we've replaced John's regular coffee grounds with
Folgers Decaffeinated. Let's see if he notices.
D'oh.
Second, you'll notice the defined($$symbol) is now something that looks a
bit hairier. :( Don't worry. Like I said, %Example:: is just a
hash. But it's the values of this hash that are magical.
The values of this hash are typeglobs. A typeglob is a variable, *foo,
that holds references to $foo, @foo, %foo, and &foo (and a bit more).
You can treat a typeglob as ANY sort of reference! So...
- if $SymbolTable::{$name} returns a typeglob...
- and a typeglob can be dereferenced to anything...
- then ${ $SymbolTable::{$name} } is like...
- $SymbolTable::name
So we've just gotten at a variable in a package, by KNOWING ITS NAME, and
getting it from the symbol table, and it's all strict compliant.
It's also very rare you'd ever have to do this. But I like to think it's
better to know some things about Perl even if you never use them.
--
Jeff "japhy" Pinyan [EMAIL PROTECTED] http://www.pobox.com/~japhy/
Are you a Monk? http://www.perlmonks.com/ http://forums.perlguru.com/
Perl Programmer at RiskMetrics Group, Inc. http://www.riskmetrics.com/
Acacia Fraternity, Rensselaer Chapter. Brother #734
*** I need a publisher for my book "Learning Perl Regular Expressions" ***