Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

Assigning variables via looping

by markusk (Novice)
on Jun 02, 2009 at 19:36 UTC ( #767748=perlquestion: print w/replies, xml ) Need Help??
markusk has asked for the wisdom of the Perl Monks concerning the following question:

Is there a 'proper' coding method of what im doing here
@names = ('peter','jonah','larry'); foreach (@names) { $$_ = "i like $_"; } print "$peter \n $jonah \n $larry \n";
It works, but only in a global scope. ie placing 'my' infront of $$_ breaks everything. Help would be appreciated. Thanks

Replies are listed 'Best First'.
Re: Assigning variables via looping
by gwadej (Chaplain) on Jun 02, 2009 at 19:48 UTC

    You are using symbolic references, which cannot point to lexical (my) variables. (use strict would have told you that.)

    In general, this is a path to much pain. You would (usually) be better off using a hash. (There are a very few cases where the symbolic references might be a better choice, but the odds of this being one of them is really slim.

    my %greeting; my @names = ('peter', 'jonah', 'larry'); foreach my $n (@names) { $greeting{$n} = "i like $n"; } print "$greeting{peter} \n $greeting{jonah} \n $greeting{larry} \n";

    Of course, there's always more than one way.

    my %greeting = map { $_ => "i like $_" } ('peter', 'jonah', 'larry'); print join( " \n ", @greeting{qw/peter jonah larry/} ), " \n";
    G. Wade
      (use strict would have told you that.)

      Well, use strict wouldn't let you use symbolic references at all. Even if you declared @names, $jonah, $peter, and $larry. Though I guess if you only enable strict for vars, not refs, that might tell you something.

Re: Assigning variables via looping
by kennethk (Abbot) on Jun 02, 2009 at 19:46 UTC
    Best practices are relative and subjective, but it's generally considered a good idea to avoid using Symbolic references without good reason. Why are you using references in place of a hash, i.e.:

    use strict; use warnings; my @names = ('peter','jonah','larry'); my %name_hash = (); foreach (@names) { $name_hash{$_} = "i like $_"; } print "$name_hash{$_}\n" foreach @names;

    In a side note, while you cannot use my on globals, you can localize their values with local. <-- not really relevant.

    Update: A useful link, as pointed out by bart in CB:;

    If you are tied to the idea of symbolic refs, you can use them with some degree of stricture with

    use strict; use warnings; my @names = ('peter','jonah','larry'); our ($peter,$jonah,$larry); foreach (@names) { no strict 'refs'; $$_ = "i like $_"; } print "$peter\n$jonah\n$larry\n";

    But read the link first.

Re: Assigning variables via looping
by eff_i_g (Curate) on Jun 02, 2009 at 20:52 UTC
    Symbolic references aside, I suggest using:
    • Strict and warnings (as my predecessors have)
    • qw() for lists (when applicable)
    • for in place of foreach
    And sometimes using:
    • A variable with for to avoid clobbering $_
      for doesn't clobber $_
      $ perl -le'$_="abc"; print for "def"; print' def abc

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://767748]
Approved by ikegami
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (3)
As of 2017-12-14 07:03 GMT
Find Nodes?
    Voting Booth?
    What programming language do you hate the most?

    Results (384 votes). Check out past polls.