The following 24 lines of code demonstrate how to do what you're describing (populating lexical "my" variables according to their symbolic names). Symbolic references don't work with lexicals, so string eval is used to inject generated code into your run. As I mentioned, the example is twenty four lines long, and I would bet that in short order people here could come up with two dozen reasons why this shouldn't be done. But injecting code into the runtime via string eval is occasionally used to accomplish tricks that you can't easily accomplish any other way. You don't have to look any further than Memoize (which I think is from the Perl core distribution) to see an example of using string eval to do something that isn't possible in another way (in that case, it's to dynamically set prototypes on manufactured functions).
So unless you're intentionally creating some deep magic, or writing a PerlMonks post, you probably ought to just forget about this:
use strict;
use warnings;
use v5.12;
my ( $a, $b, $c, $d );
my %hash = (
'a' => 'apple',
'b' => 'banana',
'c' => 'cantaloupe',
'd' => 'dice',
);
my $n = 1;
foreach my $symbol ( keys %hash ) {
say "Iteration ", $n++, ": $symbol => $hash{$symbol}";
say "\tExecuting as follows: \$$symbol = \$hash{\$symbol}\n";
eval "\$$symbol = \$hash{\$symbol}"; # <--------- The evil.
}
foreach my $symbol ( qw/a b c d/ ) {
say "\$$symbol now contains ",
eval "\$$symbol"; # Once we start the evil it's hard to stop.
}
And the output...
Iteration 1: c => cantaloupe
Executing as follows: $c = $hash{$symbol}
Iteration 2: a => apple
Executing as follows: $a = $hash{$symbol}
Iteration 3: b => banana
Executing as follows: $b = $hash{$symbol}
Iteration 4: d => dice
Executing as follows: $d = $hash{$symbol}
$a now contains apple
$b now contains banana
$c now contains cantaloupe
$d now contains dice
I won't enumerate the twenty four reasons (or more) why this isn't a good idea. But I will offer this: If you think you've got one of those situations where it's a good idea, go take a vacation or something; you're working too hard. Memoize is a pretty special case module. There are other special cases out there too. But if you were to start doing this in every day code you'll be pouring fuel on the fires of hell such that its pitchstone gates fail to contain them, thus endangering our mortal realm.
If Edsger Dijkstra were alive today he might write an article that Niklaus Wirth would rename, "String eval Considered Harmful." Just as with goto, despite its problems, there are times when it's still useful, though potentially far more harmful.
|