CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
Array question

 



Alaskan5
Novice

Jun 10, 2013, 9:53 AM

Post #1 of 11 (748 views)
Array question Can't Post

Using a sub routine, I want to print the contents of my array by row. I can't seem to figure this out. Could anyone steer me in the right direction?

Thanks


Code
#!/usr/bin/perl 
use strict;
use warnings;

my @values = (
[ 6, 5, 13 ],
[ 35, 9, 6 ],
[ 65, 255, 54 ]
);


sub get_row()
{

for($row = 0; $row < 2; $row++)
{
for($col = 0; $col < 3; $col++)
{
print "$values[$row][$col] ";
print "\n:";
}

}

}

print get_row();




Code
Global symbol "$row" requires explicit package name at line 15. 
Global symbol "$row" requires explicit package name at line 15.
Global symbol "$row" requires explicit package name at line 15.
Global symbol "$col" requires explicit package name at line 17.
Global symbol "$col" requires explicit package name at line 17.
Global symbol "$col" requires explicit package name at line 17.
Global symbol "$row" requires explicit package name at line 19.
Global symbol "$col" requires explicit package name at line 19.
Execution aborted due to compilation errors.



BillKSmith
Veteran

Jun 10, 2013, 10:20 AM

Post #2 of 11 (742 views)
Re: [Alaskan5] Array question [In reply to] Can't Post

The warnings are telling you that $row and $col must be declared with my. This would not fix all your problems. You must decide whether you want the subroutine to do the printing or to return a string that you can print. (It is probably easier to print in the subroutine in which case you would remove the word print from your last line.)

It would be much better style to pass the array to the subrotine as an argument than to access the file-scope array from within the subroutine.

The C-style loops are valid, but often have subtle problems. It is clearer and more reliable to use the foreach type of loops.

I would recommend against the use of a subroutine. Is this a homework requirement?
Good Luck,
Bill


Alaskan5
Novice

Jun 10, 2013, 10:47 AM

Post #3 of 11 (736 views)
Re: [BillKSmith] Array question [In reply to] Can't Post


In Reply To
Yeah unfortunately its a requirement to use sub



Laurent_R
Veteran / Moderator

Jun 10, 2013, 10:57 AM

Post #4 of 11 (731 views)
Re: [Alaskan5] Array question [In reply to] Can't Post

To start with, you need to declare $row and $col with the my function.

Second, this line:


Code
for($row = 0; $row < 2; $row++)


is probably wrong, as you probably want $row to takes values from 0 to 2 (including 2), so you probably want to have something like:


Code
for (my $row =0; $row < 3; $row ++)


I would rewrite the sub to something like this, using a better loop construct:


Code
sub get_row()  {  
foreach my $row (0..2) {
foreach my $col (0..2) {
print "$values [$row][$col] \n";
}
}
}


Well, to tell the truth, I would probably not put that code in a subroutine, but if I did, I would pass the array (or an array ref) as an argument to the sub rather than using @values as a global variable.

And remove the print from the last line of your code.


(This post was edited by Laurent_R on Jun 10, 2013, 10:57 AM)


Alaskan5
Novice

Jun 10, 2013, 10:59 AM

Post #5 of 11 (728 views)
Re: [BillKSmith] Array question [In reply to] Can't Post

Is there a function to allow me to print the contents of each array [ ]


Code
my @values = (  
[ 6, 5, 13 ],
[ 35, 9, 6 ],
[ 65, 255, 54 ]
);


sub get_row()
{
foreach my $values ( @values )
{
print $values . "\n";
}

}

get_row();


Output

Code
ARRAY(0x81341bc) 
ARRAY(0x81340d8)
ARRAY(0x815c948)



Alaskan5
Novice

Jun 10, 2013, 11:07 AM

Post #6 of 11 (727 views)
Re: [Laurent_R] Array question [In reply to] Can't Post

I was hoping to get an output like
6 5 13
35 9 6
65 255 54
And be able to accumulate a total per row


Code
 
my $values = @values;
my $row;
my $col;

sub get_row() {
foreach my $row (0..2) {
foreach my $col (0..2) {
print "$values [$row][$col] \n";
}
}
}

get_row();


output

Code
3 [0][0]  
3 [0][1]
3 [0][2]
3 [1][0]
3 [1][1]
3 [1][2]
3 [2][0]
3 [2][1]
3 [2][2]



Alaskan5
Novice

Jun 10, 2013, 11:51 AM

Post #7 of 11 (715 views)
Re: [Alaskan5] Array question [In reply to] Can't Post


In Reply To
I figured it out! Thanks for your help.



Laurent_R
Veteran / Moderator

Jun 10, 2013, 11:54 AM

Post #8 of 11 (714 views)
Re: [Alaskan5] Array question [In reply to] Can't Post

Just a very small stupid error on my part.

Change the relevant line to:


Code
print "$values[$row][$col] \n";


(No space between $value and the subscript)

and it should output:


Code
$ perl get_row.pl 
6
5
13
35
9
6
65
255
54


The basic idea is that, interpolated within a string, you should not leave an extra space between the name of the array and the subscript. If you leave a space, Perl does not know that is it supposed to interpolate "$values [$row][$col]" as an array of arrays. Without the space, it works.


(This post was edited by Laurent_R on Jun 10, 2013, 11:56 AM)


Laurent_R
Veteran / Moderator

Jun 10, 2013, 12:06 PM

Post #9 of 11 (712 views)
Re: [Alaskan5] Array question [In reply to] Can't Post


In Reply To
I was hoping to get an output like
6 5 13
35 9 6
65 255 54

In Reply To

Then try this version of the sub:


Code
sub get_row()  {   
foreach my $row (0..2) {
print "@{$values[$row]} \n";
}
}


To explain: $values[$row] is a reference to an array (this is why you get a memory address when you try to print it). Changing it to "@{$values[$row]}" lets you dereference this address, i.e. look at what is stored there. But references are somewhat advanced concept, if this is a school requirement and if you haven't seen references yet, then don't use this syntax and do it manually the hard way.


FishMonger
Veteran / Moderator

Jun 11, 2013, 9:41 AM

Post #10 of 11 (684 views)
Re: [Alaskan5] Array question [In reply to] Can't Post

Why are you using an empty prototype?

Why aren't you passing the array to the sub, like you should be doing?

Why are you hard coding the number of rows/columns in the nested loop?


Quote
And be able to accumulate a total per row

The output you show doesn't match that description or what your code outputs.


Code
#!/usr/bin/perl 

use 5.10.1;
use warnings;
use strict;
use List::Util qw(sum);
use Data::Dumper;

my @values = (
[ 6, 5, 13 ],
[ 35, 9, 6 ],
[ 65, 255, 54 ]
);

get_row(@values);


sub get_row {
my @total;

foreach my $row (@_) {
say join ' ', @$row;
push @total, sum @$row;
}

# you can format the output as you wish
say Dumper \@total;
}


outputs:
D:\test>test.pl

Code
6 5 13 
35 9 6
65 255 54
$VAR1 = [
'24',
'50',
'374'
];



BillKSmith
Veteran

Jun 11, 2013, 10:20 AM

Post #11 of 11 (679 views)
Re: [Alaskan5] Array question [In reply to] Can't Post


Code
print $values . "\n";

should be:

Code
print "@$values\n";

Good Luck,
Bill

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives