As others have mentioned, Perl will only evaluate strings as you have written them using eval
to invoke the compiler at runtime. You could use references as pointed out in some other answers, but that changes the way the code looks ($$a
vs $a
). However, this being Perl, there is a way to hide advanced functionality behind a simple variable, by using tie
.
{package Lazy;
sub TIESCALAR {bless \$_[1]} # store a reference to $b
sub FETCH {${$_[0]}} # dereference $b
sub STORE {${$_[0]} = $_[1]} # dereference $b and assign to it
sub new {tie $_[1] => $_[0], $_[2]} # syntactic sugar
}
my $b = 1;
Lazy->new( my $a => $b ); # '=>' or ',' but not '='
print "$a\n"; # prints 1
$b = 2;
print "$a\n"; # prints 2
You can lookup the documentation for tie
, but in a nutshell, it allows you to define your own implementation of a variable (for scalars, arrays, hashes, or file handles). So this code creates the new variable $a
with an implementation that gets or sets the current value of $b
(by storing a reference to $b
internally). The new
method is not strictly needed (the constructor is actually TIESCALAR
) but is provided as syntactic sugar to avoid having to use tie
directly in the calling code.
(which would be tie my $a, 'Lazy', $b;
)