Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Array loops and assignments

by madbee (Acolyte)
on Jul 07, 2013 at 18:22 UTC ( #1042996=perlquestion: print w/ replies, xml ) Need Help??
madbee has asked for the wisdom of the Perl Monks concerning the following question:

Hello!

Have a really silly question about arrays... Given an array, I'm trying to loop through it and assign each element to a specific variable. Below is my attempt. Variable should be: vararray index

@myNames = ('Larry', 'Curly', 'Moe'); foreach my $id(0..$#myNames) { $var.$id-> $myNames[$id]; print $id+ 1 . " $myNames[$id]\n"; } print "$var0 \n"; print "$var1 \n"; print "$var2 \n";

However, I'm getting an error message: syntax error at C:/..., near "$myNames[" Been stuck at it for sometime but cannot figure out the issue.Is this not allowed in Perl?

Is there a way I can assign each element of the array to a separate variable?

Thanks in advance, Madbee

Comment on Array loops and assignments
Download Code
Re: Array loops and assignments (symbolic references)
by LanX (Canon) on Jul 07, 2013 at 18:37 UTC
    Thats a FAQ and IMHO 99% of the cases of assignments to symbolic references in Perl are a result of weak code design (sorry!)

    the following works under no strict 'refs'

    DB<109> $var="var";$id=0 => 0 DB<110> ${$var.$id}=42 => 42 DB<111> $var0 => 42

    Are you sure you need that? Be warned about the consequences!

    Older discussions regarding 'no strict refs' might help you getting an insight why.

    edit

    Are you aware of the concept of hashes?

    Cheers Rolf

    ( addicted to the Perl Programming Language)

Re: Array loops and assignments
by davido (Archbishop) on Jul 07, 2013 at 19:24 UTC

    perlref: Symbolic references

    Why it's stupid to `use a variable as a variable name'

    There are a few really good reasons for using symbolic references. Those reasons are usually carefully tested and encapsulated in modules that isolate users from as much of the danger as possible. It's highly unlikely that you have come up with a situation that could not be better handled through a more robust means. So perlref will show you how to create and use them. Now forget that you know how. ;)


    Dave

Re: Array loops and assignments
by ww (Bishop) on Jul 07, 2013 at 19:25 UTC
    Great imagination; very little attempt to use actual Perl syntax. As a wise person observed, 'you can't just make s### up and expect the computer to understand.'

    The use of strict and warnings would have revealed that there's far more wrong than the one syntax error you cite.
    For example

    1. at line 1, you are trying to create an array... but you haven't declared it with "my ." (Did the "myNames" nomenclature confuse you? It's a waste of effort (at least in this case) to make the var name any longer than it needs to be for clarity. It might also have made it hard for you to recognize that declaration didn't happen.)
    2. at line 2, you've created (and declared; ++) the $id var, BUT it is badly misnamed as it will NOT hold an id number, but rather a name; one of the elements of the array.
      #!/usr/bin/perl use 5.016; use strict; use warnings; # madbeeWAG.pl -- WAG as in "It sure looks like madbee was doing wild +assed guessing." =head my @Names = ('Larry', 'Curly', 'Moe'); foreach my $id(0..$#Names) { say $id; # .... } output: C:\>madbeeWAG.pl 0 1 2 =cut my @Names = ('Larry', 'Curly', 'Moe'); my $id = 0; for my $name(@Names) { my $var = $name; my $varid = $var . $id; say $varid; ++$id; } #output 2 # Larry0 # Curly1 # Moe2
    3. As to breaking an array into multiple named variables, this is one (not the best, and limited but expansible) way:
      #!/usr/bin/perl use 5.016; use strict; use warnings; # madbeeWAG2.pl my ($str, $list); my @Names = ('Larry', 'Curly', 'Moe'); for my $name(@Names) { $str .= ($name . ","); } (my $listitem1, my $listitem2, my $listitem3) = split /,/, $str; say "\$listitem1: $listitem1"; say "\$listitem2: $listitem2"; say "\$listitem3: $listitem3"; =head $listitem1: Larry $listitem2: Curly $listitem3: Moe =cut

      However, a little careful study of the docs on arrays will offer several more Perl-ish and more elegant approaches. Your results will vary, more of less proportionally to the effort you put into studying the docs and the standard "Learning Perl," "Intermediate Perl," ... texts.


    If you didn't program your executable by toggling in binary, it wasn't really programming!

      @ww Thanks for your response. Yes, I did declare the variables and used strict,warnings etc. Didn't paste the entire code - just the array part. My bad!

      The requirement is that 8 elements of the array be stored in separate attributes. So instead of doing a single-assignment for each attribute, I was hoping to just put it in a loop and assign it to the corresponding variable. so, instead of: var1 = arr[0]; var2 = arr[1]; I was hoping to do: var[i] = arr[i] in a loop.

      Am sure there are more elegant and direct approaches to this. Thanks again. Will check the docs.

        It still comes back to the same question though. What can you do with $var1, $var2, $var3, $var4, etc. that you cannot do with $myNames[0], $myNames1, $myNames2...

        If you answer that, then I think you will get some more constructive solutions. What you're doing is assigning an existing numbered list of scalars, and trying to make a list of scalars which are numbered from it.

        If you really need to do a block assign, in a known order, then the construct for doing this is to put braces around your 'my' statement:

        my ( $var1, $var2, $var3, $var4 ) = @myNames;

        Will populate the vars as listed. But how do you use those var names later? You may well be jumping through a hoop you just don't need to.

        The real advantage of lists is that you actually very rarely need to reference individual elements, because you can do things like 'foreach'

        But you could do something like:

        my @var = @myNames;

        And then, you'll have $var[0] = "Curly" already.

Re: Array loops and assignments
by Preceptor (Chaplain) on Jul 07, 2013 at 19:32 UTC

    So you're taking an array, and trying to assign it to numbered variables? I'm having a tough time understanding why you would need to do this?

    I mean, you've already got that in the form of $myNames[0], etc. If you need something dynamic, a hash may be what you need.

      @Preceptor: Right. I want to store each element of the array in a variable of its own. So instead of assigning it to individual variables, I was hoping to build the variable and assign it on the fly. Makes sense? Perhaps,I'm overcomplicating this... Thanks!

        madbee:

        OK, I'll bite: Why? What are you going to be able to do with the variables that you can't already do with the array?

        ...roboticus

        When your only tool is a hammer, all problems look like your thumb.

        Definitely overcomplicating it. Try this idiom: Think of a hash as a namespace, and its elements as variables within that namespace.

        my @array = qw( Larry Curly Moe ); my %stooges; @stooges{ @array } = ( 0 .. $#array ); print "$_ = $stooges{$_}\n" for keys %stooges;

        Or if you want numbers in the name:

        %stooges = map { 'var' . $_ , $array[$_] } 0 .. $#array;

        Dave

Re: Array loops and assignments
by rjt (Deacon) on Jul 07, 2013 at 21:32 UTC

    The real problem I see is that if you really are referring to values by their index (regardless of how you accomplish that), that's probably a rather serious design problem. Then again, you say:

    The requirement is that 8 elements of the array be stored in separate attributes. So instead of doing a single-assignment for each attribute, I was hoping to just put it in a loop and assign it to the corresponding variable.

    That's actually quite a common requirement, most often seen in sub argument processing:

    my ($name, $number) = @_;

    For longer and/or variable lists of arguments, hashes provide more flexibility and basically a free namespace:

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (15)
As of 2014-12-22 15:16 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (119 votes), past polls