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

I want the new variable, tempvar in this case, to print what i gave it earlier, the color. however it only prints the words holding1 not the value I want it to have, 'green'. I'm sure I'm missing something simple but i apparently have a lack of knowledge in this area.

$holding1="green"; $holding2="blue"; $holding3="yellow"; for ($count = 3; $count >= 1; $count--) { $tempvar=holding . $count; print "$tempvar<br>"; #this prints holding1 instead of green }

Replies are listed 'Best First'.
Re: unsure how to use variable
by toolic (Bishop) on Feb 17, 2012 at 15:33 UTC
    I'm sure I'm missing something simple
    Yes... use strict and warnings. You can not construct a variable that way. You should use an array instead of individual scalar variables:
    use warnings; use strict; my @holdings = qw( green blue yellow ); for (my $count = 2 ; $count >= 0 ; $count-- ) { my $tempvar = $holdings[$count]; print "$tempvar<br>"; } print "\n"; __END__ yellow<br>blue<br>green<br>
    See also:

Re: unsure how to use variable
by moritz (Cardinal) on Feb 17, 2012 at 15:31 UTC
Re: unsure how to use variable
by jethro (Monsignor) on Feb 17, 2012 at 15:44 UTC

    What you are trying to do is implementing arrays (a very common and basic language feature). You want to execute a string so to speak. I'll tell you how that can be done, but then I tell you how to do it better, easier and much less errorprone:

    There is a function called eval() that allows you to execute strings. So you could simply write

    $tempvar= "\$holding$count"; eval " print $tempvar ";

    Now really, don't do this. eval is an instrument to do things you can't do any other way, sort of like a hominicidal maniac police officer you only give cases where everyone else failed ;-).

    Instead use arrays. You could write it this way:

    use warnings; $holding[0]="green"; $holding[1]="blue"; $holding[2]="yellow"; # or shorter: @holding= ("green","blue","yellow"); for ($count = 2; $count >= 0; $count--) { print $holding[$count]; #see, no need for a temporary variable }

    Also, always put a line "use warnings;" at the start of your script. It will tell you when you are doing something strange and will try to help you pinpoint the trouble. Case in point: It would have warned you that there is a problem with your original script

    You might like to read up on arrays in a perl book or on the internet. A feature which might confuse someone new to perl is that you write @xyz if you want to do something with the whole array, but $xyz... if you want to handle just one value from it.

    UPDATE: As oko1 said, arrays start at 0, so I had to change the loop a bit

Re: unsure how to use variable
by kennethk (Abbot) on Feb 17, 2012 at 15:44 UTC
    You are attempting to use something called Symbolic references. You will get your expected result by dereferencing your variable:

    print "$$tempvar<br>"; #this now prints the colors

    Note the extra $ sigil. However, you should probably not do it like this. This type of approach is fragile and generally results in code that is very difficult to debug and/or maintain. The easier and more reliable method, as mentioned above, is to use an array (or hash). Symbolic references are nearly always a bad design decision. For some more, see Why it's stupid to use a variable as a variable name.

    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.
Re: unsure how to use variable
by JavaFan (Canon) on Feb 17, 2012 at 16:04 UTC
    our $holding1 = "green"; our $holding2 = "blue"; our $holding3 = "yellow"; for (my $count = 3; $count >= 1; $count--) { print do {no strict 'refs'; ${"holding$count"}}, "\n"; }

      I know you're just doing your schtick and it’s nice to present a literal answer. Can’t -- that. Still, many, if not most beginner/self-taught hackers arrive at the symbolic references approach on their own. I did and it cost me plenty; slowed me down tremendously for the first year I was slinging Perl and made my code a hateful mess 5 times the size it should have been.

      So, I attach that for the OP. This works. The other suggested approaches are a better way to get your head in the game.

Re: unsure how to use variable
by oko1 (Deacon) on Feb 17, 2012 at 17:02 UTC

    And then, there is always using a hash. Arrays are great, but you have to "shift" the count to fit, since array indices (in any sane language, anyway) always start at 0.

    my %h = ( 1 => 'bleen', 2 => 'grue', 3 => 'smellow', ); for my $count (1..3){ print $h{$count}; }

    (Amazing what you can learn here if you just ask the right kind of question, isn't it? :)

    -- 
    I hate storms, but calms undermine my spirits.
     -- Bernard Moitessier, "The Long Way"

      Actually, arrays don't always start at 0. If you set:

      $[ = 1;

      ... and arrays suddenly start at 1. However (depending on what Perl version you use) $[ may be global, so set it in one place, and other code in distant modules will start acting strangely because they expect it to be set to 0. It has been made safer over time, but is still confusing. For that reason, $[ is being phased out in recent versions of Perl. 5.16 will drop support for $[ from the core code, but bundle an arybase module that implements it.

      Either way, avoid $[.

      Anyway, even if you prefer 1-based arrays over 0-based arrays, it's not a great idea to use hashes as an array substitute. For many cases (including this one), hashes are quite a bit slower.

        If we're going to nitpick: you're flat wrong in a number of places.

        • I never said that arrays start at 0. Indices, however, do - unless you change them.
        • Changing them via $[ won't make the arrays start at 1 either. Although the indices will start at whatever number is assigned to it.
        • Human language being the imperfect tool that it is, exceptions to "always" can always be found. Being able to do this is not a mark of ability, distinction, or anything else positive - especially when you end up qualifying your "correction" by saying "Either way, avoid [it]."
        • Your statement about hashes being slower is mostly misleading - badly so when trying to explain something to someone who is just learning the language. In fact, hashes are usually *much* faster than arrays - although, as always, there's the exception. Which you, of course, seized on.

        I'm totally fine - grateful, usually - when someone points out where I've been wrong; it's all a learning experience. Your post, however, was a pointless series of nitpicks and exception highlighting, and of no earthly use to anyone.

        -- 
        I hate storms, but calms undermine my spirits.
         -- Bernard Moitessier, "The Long Way"
Re: unsure how to use variable
by dkroft (Sexton) on Feb 17, 2012 at 17:35 UTC
    $holding1="green"; $holding2="blue"; $holding3="yellow"; for ($count = 3; $count >= 1; $count--) { $tempvar=${"holding" . $count}; print "$tempvar<br>"; #this prints holding1 instead of green }