in reply to Trying to automate some scalar assignments

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.


Dave

Replies are listed 'Best First'.
Re^2: Trying to automate some scalar assignments
by runrig (Abbot) on Sep 22, 2011 at 20:58 UTC
    Oh come on...if you're going to muck with symbolic references, let's muck with symbolic references (and the symbol table) (-:
    my %hash = (a => 1, b => 2, c => 3, d => 4); for (keys %hash) { *$_ = \$hash{$_}; } $hash{c} = "foobar"; print "$c\n";
    (Caveat: This does not use 'my' variables, but then, the OP didn't say that they were required)

      Well that's run-of-the-mill evil. :)

      I did consider the global symbol table, but the first line of sample code provided by the OP was, "my($a, $b, $c, $d);", so I assumed he really was trying to manipulate lexicals symbolically. Either way we're both going to need to wash our hands in hot water with pumice soap now.


      Dave

        Awesome, folks, thanks!