6

Why does this print 42:

$answer = 42;
$variable = "answer";

print ${$variable} . "\n";

but this doesn't:

my $answer = 42;
my $variable = "answer";

print ${$variable} . "\n";
brian d foy
  • 129,424
  • 31
  • 207
  • 592
ennuikiller
  • 46,381
  • 14
  • 112
  • 137
  • I'm guessing that $answer defines a global scope, and my $answer defines a local scope. – Paul Nathan Feb 25 '10 at 23:20
  • @Paul, but print $answer would work fine....how does ${$variable} create a global scope? – ennuikiller Feb 25 '10 at 23:22
  • 2
    Always use `use strict; use warnings;` and you'll never see this problem. Even better, never use the value of a variable to get at another variable. Hashes are much better. – Ether Feb 25 '10 at 23:31
  • 1
    Well, you'll see the problem with strict, which is the point of strict. :) – brian d foy Feb 25 '10 at 23:34
  • 2
    If you have a really, really good reason to do this, `PadWalker` exists to facilitate such hacks. But if your reason is "just curious", then stick with the "don't do this then" answer. – hobbs Feb 26 '10 at 01:21

4 Answers4

15

Only package variables (the kind declared in your first example) can be targeted via symbolic references. Lexical (my) variables, cannot be, which is why your second example fails.

See the excellent article Coping with Scoping for how the two separate variable systems in Perl operate. And see the also excellent Why it's stupid to use a variable variable name for why that's stupid. :)

cjm
  • 61,471
  • 9
  • 126
  • 175
friedo
  • 65,762
  • 16
  • 114
  • 184
6

Perl has two entirely separate but largely compatible variable systems, package variables, as in your first example, and lexical variables, as in the second. There are a few things that each can do but the other cant:

Package variables are the only ones that can be:

  1. localized (with local)
  2. used as the target for a symbolic reference (the reason the OP's second example doesnt work)
  3. used as barewords (sub definitions, file handles)
  4. used with typeglobs (because that's what the symbol really is under the hood)

Lexical variables are the only ones that can be closed over (used in a lexical closure).

Using strict would help by forcing you to declare package variables with our, making the difference clearer.

There are several times where symbolic references are useful in Perl, most center around manipulating the symbol table (like writing your own import in a module rather than using Exporter, monkey-patching modules at runtime, various other meta-programming tasks). All of these are advanced topics.

For other tasks, there is usually a better way to do it such as with a hash. The general rule of thumb is to always run under use warnings; use strict; unless you know there isn't any other way but to disable a portion of the pragma (such as using no strict 'refs'; in as small a scope as possible).

Eric Strom
  • 39,821
  • 2
  • 80
  • 152
5

The problem is that you can't use a symbolic reference to refer to a lexical variable. In both examples ${$variable} is looking for $main::answer. In the first, $answer is a package global and short for $main::answer, so the reference finds it. In the second, $answer is a lexical variable and doesn't live in any package, so the reference can't find it.

More details in perlref under heading Symbolic references.

brian d foy
  • 129,424
  • 31
  • 207
  • 592
Philip Potter
  • 8,975
  • 2
  • 37
  • 47
5

Symbolic references only work with package variables. The symbol table doesn't track lexical variables (which is the entire point of them being lexical :).

brian d foy
  • 129,424
  • 31
  • 207
  • 592