Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

loop to allocate values to variables

by travisbickle34 (Beadle)
on Aug 17, 2005 at 14:49 UTC ( #484455=perlquestion: print w/replies, xml ) Need Help??

travisbickle34 has asked for the wisdom of the Perl Monks concerning the following question:

I have a long list of variables to which I want to allocate values. The values to be allocated populate a hash and the keys of the hash are the variable names preceeded by an underscore.

i.e. the variable  $blastresult needs to be allocated the value accessed by  $$self{_blastresult}

There are around 20 variables in all so I would like to allocate the values in some sort of foreach loop. For example, using 2 variables for simplicity's sake I would like to do something like:

 foreach my ($blastresult, $value) {$_ = $$self{_$_};}

I can see the reasons why this particular code won't work, but can't see how I can fix it! Any help would be appreciated.

Cheers in advance,


Replies are listed 'Best First'.
Re: loop to allocate values to variables
by holli (Abbot) on Aug 17, 2005 at 15:11 UTC
    That seems a bit odd to me. You already have a hash, so why not work with that directly instead of putting its contents into independent variables.

    However, this code:
    foreach my ($blastresult, $value) {$_ = $$self{_$_};}
    is not doing what you think it does. It is just looping over the two values.
    my $blastresult = "foo"; my $value = "bar"; foreach my ($blastresult, $value) {print;}
    prints "foobar". What you want would be more along the lines of
    use strict; use warnings; my $foo; my $bar; my %hash = ("_foo" => "FOO", "_bar" => "BAR"); foreach my $varname (keys %hash) { eval "\$" . substr($varname,1) . " = '" . $hash{$varname} . "';"; } print "$foo\n$bar";

    holli, /regexed monk/
Re: loop to allocate values to variables
by gryphon (Abbot) on Aug 17, 2005 at 15:27 UTC

    Greetings travisbickle34,

    First off, I would strongly recommend you try to redesign your code a bit to not require this. As merlyn likes to point out, when you have to define 20 variables with my, something's wrong. However, if you must do it this way, you could try:

    no strict; no warnings; my %variables = ( '_blastresult' => 1138, 'skip_me' => 0, '_stormtroopers' => 42 ); foreach (keys %variables) { eval '$' . $1 . ' = ' . $variables{$_} if (/^_(.*)/s); } print $blastresult;

    Could you post a little bit more of the problem you're trying to solve? I'd rather recommend a better way than what I've posted above.

    gryphon Development Manager (DSMS)
    code('Perl') || die;

Re: loop to allocate values to variables
by Codon (Friar) on Aug 17, 2005 at 16:08 UTC

    I'm going to have to agree with holli on this and say Why not just use the hash? If you must do something like this, know that it is in violation of some of the tenets of strict. Here's a version with limited un-strict-ness that does not use an eval:

    #!/usr/bin/perl -l use strict; use warnings; my %foo = ( _foo => 'FOO', _bar => 'BAR', _baz => 'BAZ', zum => 'ZUM', # do not make this one a "real" variable ); { # limit the scope of the following 'no strict' no strict 'refs'; # There be magic here! This will get the keys from %foo # then attempt to remove the leading '_'. If it works, # the *modified* key gets passed along; otherwise, the # key is stripped from your processing list. We then # dynamically create a variable with the name of the # modified key and assign it the value of the unmodified # key in the hash. $$_ = $foo{"_$_"} for (grep { s/^_(.*)/$1/ } keys %foo); } # this is so we can speak the variable's name without Perl throwing a +fit no strict 'vars'; print for ($foo, $bar, $baz, $zum); # should produce one 'unitialized +' warning
    I don't agree that this is good practice. However, do what you must to get the task accomplished. I know too well what it is to maintain ugly code, even when the original author was me.

    Ivan Heffner
    Sr. Software Engineer, DAS Lead, Inc.
Re: loop to allocate values to variables
by radiantmatrix (Parson) on Aug 17, 2005 at 18:51 UTC

    I can't imagine why you'd need to take the values in a hash and populate them to variable names -- you already have a hash! Why do you want to do this?

    Instead of creating and using $blastresult, why can you not use $self->{_blastresult} wherever you need that value?

    If you must, you could:

    while (my ($k,$v) = each %$self) { $k =~ s/^_//; eval '$'.$k.'= $v'; }
    Larry Wall is Yoda: there is no try{} (ok, except in Perl6; way to ruin a joke, Larry! ;P)
    The Code that can be seen is not the true Code
    "In any sufficiently large group of people, most are idiots" - Kaa's Law
      Hmmm. Having read these replies I honestly don't know why I didn't just opt to use the hash values :-/

      That's the route I'm going to take now though.

      Thanks for highlighting the insane nature of my question!

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://484455]
Approved by planetscape
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (4)
As of 2020-12-02 06:05 GMT
Find Nodes?
    Voting Booth?
    How often do you use taint mode?

    Results (32 votes). Check out past polls.