Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

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: (8)
As of 2017-06-25 13:12 GMT
Find Nodes?
    Voting Booth?
    How many monitors do you use while coding?

    Results (567 votes). Check out past polls.