LinuxQuestions.org
Help answer threads with 0 replies.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 03-11-2008, 10:25 AM   #1
littletransformer
LQ Newbie
 
Registered: Nov 2007
Posts: 18

Rep: Reputation: 0
Unhappy Confused: how to use variable as the name of an array in perl


I want to use variable as the name of an array in perl,but it doesn't seem to work.If so,what can I do to reach that purpose.The code:
@array_1=qw(one two three four five);
@array_2=qw(one two three four);
@array_3=qw(one two three);
@array_4=qw(one two);
@array_5=qw(one);
for($i=1;$i<=5;$i++)
{
print "array_$i: ",@array_$i,"\n";
}
I know the problem lie in '@array_$i',but I have no idea how to change it.
 
Old 03-11-2008, 10:51 AM   #2
exscape
Member
 
Registered: Aug 2007
Location: Sweden
Distribution: OS X, Gentoo, FreeBSD
Posts: 82

Rep: Reputation: 15
I'm very new at perl myself, but I think nested arrays (using references) would be a better idea. Not sure if the above is even possible, but as I said, really new (finished 'Learning perl' yesterday).
 
Old 03-11-2008, 12:37 PM   #3
forrestt
Senior Member
 
Registered: Mar 2004
Location: Cary, NC, USA
Distribution: Fedora, Kubuntu, RedHat, CentOS, SuSe
Posts: 1,288

Rep: Reputation: 99
Perl doesn't understand that because it thinks @array_ and $i are two variables, and since they aren't in quotes, they need an operator between them (thus the "Scalar found where operator expected at..." error you should be getting).

To get around this, you need to create a variable to hold the array name so the @ and the $ can be right next to each other and thus looked at by perl to be a single variable (what you are after).

This will do what you are saying you want above:

Code:
#!/usr/bin/perl

@array_1=qw(one two three four five);
@array_2=qw(one two three four);
@array_3=qw(one two three);
@array_4=qw(one two);
@array_5=qw(one);

for($i=1;$i<=5;$i++) {
    $arrayName = "array_$i";
    print "$arrayName: " .  @$arrayName . "\n";
}
But, I don't think that is what you are trying to do. You can't just print an array in perl and get it's contents. What you probably want is something like:

Code:
#!/usr/bin/perl

@array_1=qw(one two three four five);
@array_2=qw(one two three four);
@array_3=qw(one two three);
@array_4=qw(one two);
@array_5=qw(one);

for($i=1;$i<=5;$i++) {
    $arrayName = "array_$i";
    print "$arrayName:\n";
    foreach (@$arrayName) {
        print "         $_\n";
    }
    print "\n";
}
HTH

Forrest
 
Old 03-11-2008, 01:29 PM   #4
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 70
How about this:
Code:
#!/usr/bin/perl

@array_1=qw(one two three four five);
@array_2=qw(one two three four);
@array_3=qw(one two three);
@array_4=qw(one two);
@array_5=qw(one);

for($i=1; $i<=5; $i++) {
	local $, = " ";
	print "array_$i:", eval("\@array_$i"), "\n";
}
 
Old 03-11-2008, 01:57 PM   #5
forrestt
Senior Member
 
Registered: Mar 2004
Location: Cary, NC, USA
Distribution: Fedora, Kubuntu, RedHat, CentOS, SuSe
Posts: 1,288

Rep: Reputation: 99
OK, just to explain osor's code:

The line 'local $, = " ";' changes the OUTPUT_FIELD_SEPARATOR from the default of NULL to a space. This means that in order for perl to think that it has two variables, they have to be separated by a space. Since @array_ and $i in "\@array_$i" aren't separated by a space, it is seen as a single variable. The \ in front of the @ sign means use a pointer, so it is sending a pointer to the array @array_$i to the eval function instead of the array itself (you can't really send arrays to functions as the function would see it as a bunch of parameters, not one).

HTH

Forrest
 
Old 03-11-2008, 02:50 PM   #6
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 70
Quote:
Originally Posted by forrestt View Post
The line 'local $, = " ";' changes the OUTPUT_FIELD_SEPARATOR from the default of NULL to a space. This means that in order for perl to think that it has two variables, they have to be separated by a space. Since @array_ and $i in "\@array_$i" aren't separated by a space, it is seen as a single variable.
No. It means to print a space in between each element of the list. So
Code:
print 1,2,3;
will have the output
Code:
123
But
Code:
$, = " ";
print 1,2,3;
will have the output
Code:
1 2 3
Quote:
Originally Posted by forrestt View Post
The \ in front of the @ sign means use a pointer, so it is sending a pointer to the array @array_$i to the eval function instead of the array itself (you can't really send arrays to functions as the function would see it as a bunch of parameters, not one).
There are no pointers (or the Perl term—references) at all. What I have is a string in which I want to interpolate $i, but don’t want to interpolate @array_. For example, if I had said
Code:
print "@array_$i";
the output in the first loop iteration would be (remember that strictures and warnings are turned off):
Code:
1
since the value of $i is 1 and @array_ is undefined (so it is interpolated as empty). Instead I want to print the following:
Code:
@array_1
so I have to tell Perl to treat the @ as a literal ‘@’ and perform no interpolation:
Code:
print "\@array_$i";
I probably should have explained this all in my other post. The Perl builtin eval takes a string and interprets it as a Perl expression. So
Code:
eval "print \$i";
is a fancy way of saying
Code:
print $i;
In the case where you want variables made up of strings, eval comes in handy (but there are many other uses of eval).

Last edited by osor; 03-11-2008 at 03:03 PM. Reason: better example of eval
 
Old 03-11-2008, 03:29 PM   #7
forrestt
Senior Member
 
Registered: Mar 2004
Location: Cary, NC, USA
Distribution: Fedora, Kubuntu, RedHat, CentOS, SuSe
Posts: 1,288

Rep: Reputation: 99
Ok, I guess I need to go back to Perl school (been a few years since I did Perl on a regular basis).

/me goes and crawls under a rock.
 
Old 03-11-2008, 04:01 PM   #8
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: FreeBSD, Debian, Mint, Puppy
Posts: 3,298

Rep: Reputation: 175Reputation: 175
Quote:
You can't just print an array in perl and get it's contents.
oh yes you can,
Quote:

@L = qw(mick keef bill charlie ronnie);
local $\ = "\n\n"; # default EOL for print

print "without quotes:", @L;
print "with quotes:", "@L";

local $" = "\n"; # default list seperator in quotes

print "and finally:\n", "@L";
Quote:

$ ./1.pl
without quotes:mickkeefbillcharlieronnie

with quotes:mick keef bill charlie ronnie

and finally:
mick
keef
bill
charlie
ronnie
 
Old 03-11-2008, 04:13 PM   #9
forrestt
Senior Member
 
Registered: Mar 2004
Location: Cary, NC, USA
Distribution: Fedora, Kubuntu, RedHat, CentOS, SuSe
Posts: 1,288

Rep: Reputation: 99
OK, I'm staying under my rock.
 
Old 03-11-2008, 08:17 PM   #10
chrism01
Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Centos 6.5, Centos 5.10
Posts: 16,311

Rep: Reputation: 2040Reputation: 2040Reputation: 2040Reputation: 2040Reputation: 2040Reputation: 2040Reputation: 2040Reputation: 2040Reputation: 2040Reputation: 2040Reputation: 2040
All the above being said, it's generally regarded as a bad idea to to what you asked originally (ie store var names in other vars).
As mentioned, put the arrays in another array as array refs, and go from there eg
Code:
@all_arrs = (\@arr1, \@arr2, ...);
for $arr_ref (@all_arrs)
{
    print "@{$arr_ref}\n";
}
 
Old 03-12-2008, 12:29 AM   #11
littletransformer
LQ Newbie
 
Registered: Nov 2007
Posts: 18

Original Poster
Rep: Reputation: 0
Question more details

Quote:
Originally Posted by chrism01 View Post
All the above being said, it's generally regarded as a bad idea to to what you asked originally (ie store var names in other vars).
As mentioned, put the arrays in another array as array refs, and go from there eg
Code:
@all_arrs = (\@arr1, \@arr2, ...);
for $arr_ref (@all_arrs)
{
    print "@{$arr_ref}\n";
}
I do think you almost solve the problem,but I wonder what I can do if the the number of elements in @arr_arrs remain uncertain. If so, it seems to go in to circulation that never ends...
 
Old 03-12-2008, 01:32 AM   #12
chrism01
Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Centos 6.5, Centos 5.10
Posts: 16,311

Rep: Reputation: 2040Reputation: 2040Reputation: 2040Reputation: 2040Reputation: 2040Reputation: 2040Reputation: 2040Reputation: 2040Reputation: 2040Reputation: 2040Reputation: 2040
Well, you wouldn't noramlly hard-code all those arrays in the first place, so adding one more line is no problem.

I'm not sure why you're doing this, but typically (in real code) I'd be doing something like:

Code:
# Create arr of arr refs for each row of a DB SELECT


    # Run the select
    $sth = $cfg::dbh->prepare($sql);
    $sth->execute();
    if ( $sth->errstr )
    {
        # SQL failure; log err msg from DB and email Sys Admin
        $error_msg = "db_get_rpt_physical_servers(): ".localtime()." ".
                                            $sth->errstr."\n".$sql;
        error_handler($error_msg);
    }
    else
    {
        # Collect values
        while( @db_row = $sth->fetchrow() )
        {
            # Load new record arr ref:
            $data_rec = [ $db_row[0], $db_row[1], $db_row[2], $db_row[3] ];

            # Add to list
            push(@physical_servers_recs, $data_rec);
        }
    }

# some time later, output as a  csv file

    # Create file and output results
    open( CSV_FILE, ">>", "$rpt_file" ) or
                    error_handler("Unable to open file: $rpt_file: $!\n");
    print CSV_FILE "$table_name\n\n";
    print CSV_FILE "$col_names\n\n";

    # Already sorted by SQL
    for $rec ( @data_rows )
    {
        print CSV_FILE join(',', @{$rec})."\n";
    }
    print CSV_FILE "\nTotal ".scalar(@data_rows)."\n\n";
    close(CSV_FILE) or
                error_handler("Unable to close file: $rpt_file: $!\n");
HTH
 
Old 03-12-2008, 07:32 PM   #13
littletransformer
LQ Newbie
 
Registered: Nov 2007
Posts: 18

Original Poster
Rep: Reputation: 0
Exclamation

Maybe I should expain it more specifically.
If the number of the array is determined by another variabel $index, and I want to display the content in each array,
but obviously code as below would not work:

for($i=1;$i<=$index-6;$i++)
{
push(@srl_$i,$line_in[5+$i]);
}
do you have any ideas how I can deal this?
 
Old 03-12-2008, 08:47 PM   #14
chrism01
Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Centos 6.5, Centos 5.10
Posts: 16,311

Rep: Reputation: 2040Reputation: 2040Reputation: 2040Reputation: 2040Reputation: 2040Reputation: 2040Reputation: 2040Reputation: 2040Reputation: 2040Reputation: 2040Reputation: 2040
You shouldn't mormally use counted loops in Perl.
If you look at my code you'll see that $data_rec is a dynamically created 'anonymous array ref', and you then add (push) each of these into another array.

As I said before, it depends on whether you have to have hardcoded array names, or if you can create them dynamically (ie create an array_ref ($aref) and cast to an array on demand ( @{$aref} ).

The latter is preferred if you don't know how many arrays you need.

Maybe you need to explain more about your app, as to why you'd want to do this.
 
Old 03-13-2008, 12:28 AM   #15
littletransformer
LQ Newbie
 
Registered: Nov 2007
Posts: 18

Original Poster
Rep: Reputation: 0
Question

Ok,I will do it.
I want to collect data from the column-format file, for example,the original file may be like this,

1 a1 b1 c1
2 a2 b2 c2
3 a3 b3 c3

4 a4 b4 c4 d4
5 a5 b5 c5 d5
6 a6 b6 c6 d6

7 a7 b7 c7
8 a8 b8 c8

as you can see from above,I want to colloct and store data in each column into @array_1,@array_2,...,@array_i,...
but the number of collumns is changeable, sometimes 3,sometime 4,then 3,or later 5.so I have to make the @array_i changeable.
That's why I am confused about the usage.
If there are other things you are not clear about ,I can explain it.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
About the array variable sean_zhang Linux - Newbie 3 02-27-2008 01:01 AM
Bash indirect reference to array variable(s) sixerjman Programming 6 10-25-2006 12:18 PM
PERL: Size of an array of an Array inspleak Programming 2 03-10-2004 03:24 PM
Variable Array in C mojozoox Programming 6 12-16-2003 02:39 AM
Assigning a string to a variable (not a pointer, not a array) JStew Programming 3 11-18-2002 09:13 AM


All times are GMT -5. The time now is 02:00 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration