niXforums Forum Index
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   PreferencesPreferences   Log in to check your private messagesLog in to check your private messages   Log inLog in 
·  nixdoc.net ·  man pages ·  Linux HOWTOs ·  FreeBSD Tips ·  Forums
navigation Forum index » Programming » Perl
Problem with passing array to subroutine
Post new topic   Reply to topic Page 1 of 1 [12 Posts] View previous topic :: View next topic
Author Message
benkasminbullock@gmail.co
*nix forums beginner


Joined: 14 May 2006
Posts: 33

PostPosted: Thu May 25, 2006 2:51 pm    Post subject: Problem with passing array to subroutine Reply with quote

Can anyone explain what I'm doing wrong in the following? The output is
something like this:

Quote:
Begin output

First try:
1 X 1: A
1 X 2: B
1 X 3: C
2 X 1: D
2 X 2: E
2 X 3: F
3 X 1: G
3 X 2: H
3 X 3: I
Try again:
1 X 1: A
1 X 2: B
1 X 3: C
2 X 1: D
2 X 2: E
2 X 3: F
3 X 1: G
3 X 2: H
3 X 3: I
Now what happens:
Total size 3 X 3
1 X 1: Not defined
1 X 2: Not defined
1 X 3: Not defined
2 X 1: Not defined
2 X 2: Not defined
2 X 3: Not defined
3 X 1: Not defined
3 X 2: Not defined
3 X 3: Not defined

<<<<<<<<<<<<<<<<<<<<<<<<<

I don't know why I get the "Not defined" in the last part. I think it's an
error in calling the subroutine but I'm not sure what I should do to get
the correct syntax.

The following is the shortest I could make my sample program. This is a
complete running example.

============================

#!/usr/bin/perl -w
use strict;

sub read_table
{
my $input_text = $_[0]; # assumes the table text is in the first argument
$input_text =~ m/\{\|(.*?)\|\}/s;
my @rows;
my $table_text = $1;
my @row_text = split (/\|\-/s, $table_text);
my $row_number = 0;
my $n_columns = 0;
my $column_number;
my %cell;
foreach my $rt (@row_text) {
# print "rt='$rt'\n";
$column_number = 0;
$row_number++;
chomp $rt;
while ($rt =~ s/\|(.*)//) {
$column_number++;
$cell{"text"} = $1;
# print "text = '$1' rt = '$rt'";
$rows[$row_number][$column_number] = { %cell };
}
if ($column_number > $n_columns) {
$n_columns = $column_number;
}
}
$rows[0][0] = [$row_number, $n_columns];
for (my $x = 1; $x <= $row_number; $x++) {
for (my $y = 1; $y <= $n_columns; $y++) {
print "$x X $y: ";
my $cell_ref = $rows[$x][$y];
if ($cell_ref) {
my %cell = %$cell_ref;
print $cell{"text"};
} else {
print "Not defined";
}
print "\n";
}
}
return @rows;
}

sub print_table
{
my @rows = $_[0];
my $dim = $rows[0][0];
if (! $dim) {
print "No dimensions in table.\n";
return;
}
my @dimensions = @$dim;
my $row_number = $dimensions[0];
my $n_columns = $dimensions[1];
print "Total size $row_number X $ n_columns\n";
for (my $x = 1; $x <= $row_number; $x++) {
for (my $y = 1; $y <= $n_columns; $y++) {
print "$x X $y: ";
my $cell_ref = $rows[$x][$y];
if ($cell_ref) {
my %cell = %$cell_ref;
print $cell{"text"};
} else {
print "Not defined";
}
print "\n";
}
}
}

my $text = <<ENDTEXT;
{|
|A
|B
|C
|-
|D
|E
|F
|-
|G
|H
|I
|}
ENDTEXT

print "First try:\n";
my @table = read_table ($text);
print "Try again:\n";
for (my $x = 1; $x <= 3; $x++) {
for (my $y = 1; $y <= 3; $y++) {
print "$x X $y: ";
my $cell_ref = $table[$x][$y];
if ($cell_ref) {
my %cell = %$cell_ref;
print $cell{"text"};
} else {
print "Not defined";
}
print "\n";
}
}
print "Now what happens:\n";
print_table (@table);
Back to top
xhoster@gmail.com
*nix forums Guru


Joined: 19 Jul 2005
Posts: 842

PostPosted: Thu May 25, 2006 3:06 pm    Post subject: Re: Problem with passing array to subroutine Reply with quote

Ben Bullock <benkasminbullock@gmail.com> wrote:
Quote:
Can anyone explain what I'm doing wrong in the following?

Thanks for posting a working program. But with a script this large (and
ugly), you should have provided a little more exposition about what purpose
each part served.

Anyway,

....
Quote:

sub print_table
{
my @rows = $_[0];

since you pass in the whole array, you need to capture the whole
array, not just the first element of it, in @rows:

my @rows = @_;
....
Quote:
}
....


Quote:
print_table (@table);


Xho

--
-------------------- http://NewsReader.Com/ --------------------
Usenet Newsgroup Service $9.95/Month 30GB
Back to top
David Squire
*nix forums Guru Wannabe


Joined: 08 Apr 2006
Posts: 197

PostPosted: Thu May 25, 2006 3:08 pm    Post subject: Re: Problem with passing array to subroutine Reply with quote

Ben Bullock wrote:
Quote:
Can anyone explain what I'm doing wrong in the following?

[snip]

Quote:
I don't know why I get the "Not defined" in the last part. I think it's an
error in calling the subroutine but I'm not sure what I should do to get
the correct syntax.

Correct. You are passing a list of values to print_table, which is then
trying to assign the first element of that list to an array. Focussing
just on the quickest fix I could come up with for your code:

[snip]

Quote:
sub print_table
{
my @rows = $_[0];

Change to:

sub print_table
{
my $table_ref = shift;
my @rows = @{$table_ref};

[snip]

Quote:
print_table (@table);

Change to:

print_table (\@table);

Moral: it's always a good idea to pass *references* to large and complex
data structures.

DS
Back to top
xhoster@gmail.com
*nix forums Guru


Joined: 19 Jul 2005
Posts: 842

PostPosted: Thu May 25, 2006 3:10 pm    Post subject: Re: Problem with passing array to subroutine Reply with quote

David Squire <David.Squire@no.spam.from.here.au> wrote:

Quote:
Change to:

sub print_table
{
my $table_ref = shift;
my @rows = @{$table_ref};

[snip]

print_table (@table);

Change to:

print_table (\@table);

Moral: it's always a good idea to pass *references* to large and complex
data structures.

Since you are just copying the whole thing anyway with the
my @rows = @{$table_ref}, what is the point of passing the reference
rather than passing the array itself (and using my @rows=@_)?

Xho

--
-------------------- http://NewsReader.Com/ --------------------
Usenet Newsgroup Service $9.95/Month 30GB
Back to top
Brian Wakem
*nix forums Guru


Joined: 26 Feb 2005
Posts: 320

PostPosted: Thu May 25, 2006 3:11 pm    Post subject: Re: Problem with passing array to subroutine Reply with quote

Ben Bullock wrote:

Quote:
Can anyone explain what I'm doing wrong in the following? The output is
something like this:

Begin output

First try:
1 X 1: A
1 X 2: B
1 X 3: C
2 X 1: D
2 X 2: E
2 X 3: F
3 X 1: G
3 X 2: H
3 X 3: I
Try again:
1 X 1: A
1 X 2: B
1 X 3: C
2 X 1: D
2 X 2: E
2 X 3: F
3 X 1: G
3 X 2: H
3 X 3: I
Now what happens:
Total size 3 X 3
1 X 1: Not defined
1 X 2: Not defined
1 X 3: Not defined
2 X 1: Not defined
2 X 2: Not defined
2 X 3: Not defined
3 X 1: Not defined
3 X 2: Not defined
3 X 3: Not defined



I don't know why I get the "Not defined" in the last part. I think it's an
error in calling the subroutine but I'm not sure what I should do to get
the correct syntax.

The following is the shortest I could make my sample program. This is a
complete running example.

============================

#!/usr/bin/perl -w
use strict;

sub read_table
{
my $input_text = $_[0]; # assumes the table text is in the first
argument $input_text =~ m/\{\|(.*?)\|\}/s;
my @rows;
my $table_text = $1;
my @row_text = split (/\|\-/s, $table_text);
my $row_number = 0;
my $n_columns = 0;
my $column_number;
my %cell;
foreach my $rt (@row_text) {
# print "rt='$rt'\n";
$column_number = 0;
$row_number++;
chomp $rt;
while ($rt =~ s/\|(.*)//) {
$column_number++;
$cell{"text"} = $1;
# print "text = '$1' rt = '$rt'";
$rows[$row_number][$column_number] = { %cell };
}
if ($column_number > $n_columns) {
$n_columns = $column_number;
}
}
$rows[0][0] = [$row_number, $n_columns];
for (my $x = 1; $x <= $row_number; $x++) {
for (my $y = 1; $y <= $n_columns; $y++) {
print "$x X $y: ";
my $cell_ref = $rows[$x][$y];
if ($cell_ref) {
my %cell = %$cell_ref;
print $cell{"text"};
} else {
print "Not defined";
}
print "\n";
}
}
return @rows;
}

sub print_table
{
my @rows = $_[0];


my @rows = @_;



--
Brian Wakem
Email: http://homepage.ntlworld.com/b.wakem/myemail.png
Back to top
David Squire
*nix forums Guru Wannabe


Joined: 08 Apr 2006
Posts: 197

PostPosted: Thu May 25, 2006 3:23 pm    Post subject: Re: Problem with passing array to subroutine Reply with quote

David Squire wrote:
Quote:
Ben Bullock wrote:
Can anyone explain what I'm doing wrong in the following?

[snip]
Quote:

sub print_table
{
my @rows = $_[0];

Change to:

sub print_table
{
my $table_ref = shift;
my @rows = @{$table_ref};

[snip]

print_table (@table);

Change to:

print_table (\@table);

Moral: it's always a good idea to pass *references* to large and complex
data structures.

.... and of course it would then be sensible to keep using $table_ref,
dereferencing it when needed, instead of copying the whole thing to
@rows, particularly if the table is large, e.g.

Quote:
my $dim = $rows[0][0];

would become:

my $dim = $$table_ref[0][0];

or perhaps more clearly:

my $dim = $table_ref->[0][0];

DS
Back to top
David Squire
*nix forums Guru Wannabe


Joined: 08 Apr 2006
Posts: 197

PostPosted: Thu May 25, 2006 3:25 pm    Post subject: Re: Problem with passing array to subroutine Reply with quote

xhoster@gmail.com wrote:
Quote:
David Squire <David.Squire@no.spam.from.here.au> wrote:

Change to:

sub print_table
{
my $table_ref = shift;
my @rows = @{$table_ref};

[snip]

print_table (@table);
Change to:

print_table (\@table);

Moral: it's always a good idea to pass *references* to large and complex
data structures.

Since you are just copying the whole thing anyway with the
my @rows = @{$table_ref}, what is the point of passing the reference
rather than passing the array itself (and using my @rows=@_)?

True... as I address in my own follow-up to my own post Smile (written
while you were writing this). I am in the habit of passing references in
that situation, and it was a way of doing that, and then making the OP's
code work with minimal changes.

DS
Back to top
Tad McClellan
*nix forums Guru


Joined: 09 Mar 2005
Posts: 1647

PostPosted: Thu May 25, 2006 9:18 pm    Post subject: Re: Problem with passing array to subroutine Reply with quote

Ben Bullock <benkasminbullock@gmail.com> wrote:

Quote:
#!/usr/bin/perl -w


use warnings; # is much better than the -w switch, because it is scoped


Quote:
$input_text =~ m/\{\|(.*?)\|\}/s;
my @rows;
my $table_text = $1;


You should never use the dollar-digit variables unless you have
first ensured that the match *succeeded*, else they will contain
stale values from some previous match that did succeed.

die "'$input_text' did not match" unless $input_text =~ m/\{\|(.*?)\|\}/s;
my $table_text = $1;


Quote:
my @row_text = split (/\|\-/s, $table_text);


The m//s modifier changes the meaning of dot, it is useless
when there is no dot in your regex.

Hyphen is not special in regexes, so there is no need to escape it.


Quote:
while ($rt =~ s/\|(.*)//) {


Q: How many times will that loop iterate?

A: One.

It is a loop that does not loop!

So then, why is it in a loop?


if ($rt =~ s/\|(.*)//) {


--
Tad McClellan SGML consulting
tadmc@augustmail.com Perl programming
Fort Worth, Texas
Back to top
benkasminbullock@gmail.co
*nix forums beginner


Joined: 14 May 2006
Posts: 33

PostPosted: Fri May 26, 2006 12:09 am    Post subject: Re: Problem with passing array to subroutine Reply with quote

"Tad McClellan" <tadmc@augustmail.com> wrote in message
news:slrne7c7pf.ef3.tadmc@magna.augustmail.com...
Quote:
Ben Bullock <benkasminbullock@gmail.com> wrote:

#!/usr/bin/perl -w


use warnings; # is much better than the -w switch, because it is scoped

Thanks for that tip.

Quote:

$input_text =~ m/\{\|(.*?)\|\}/s;
my @rows;
my $table_text = $1;


You should never use the dollar-digit variables unless you have
first ensured that the match *succeeded*, else they will contain
stale values from some previous match that did succeed.

In fact, in the original program, I did that; this is a quick running
example to demonstrate only one problem I had. I deliberately removed lots
of testing of input and various conditionals in order to make the program
short enough to be postable.

Quote:
die "'$input_text' did not match" unless $input_text =~
m/\{\|(.*?)\|\}/s;
my $table_text = $1;


my @row_text = split (/\|\-/s, $table_text);


The m//s modifier changes the meaning of dot, it is useless
when there is no dot in your regex.

In this case, again, I simplified the regexp to a "minimal" version and
forgot to remove the s.

Quote:
Hyphen is not special in regexes, so there is no need to escape it.

Thanks for that tip.

Quote:
while ($rt =~ s/\|(.*)//) {


Q: How many times will that loop iterate?

A: One.

A: Three? Or else why does it print three results?

Quote:
It is a loop that does not loop!

No, it is a loop which does indeed loop. Try replacing the above with

$rt =~ s/\|(.*)//;

in my original code (also removing the end } of the "while") and you'll see
that the output results are different.

Thanks for the other code critiques too. But I feel like I have wasted your
time somewhat; the above example program is a stripped-down-for-posting
version of a much longer program, with all kinds of extra conditionals and
odd bits, which is why there is some possibly redundant or odd-looking code
in there. I should have said that more clearly to save your time.

Anyway, as a meta-query, would it be better to post the whole code of my
program or to post this kind of minimal script? The posting guidelines
(which everyone seems so keen on) currently suggest posting the minimal
item.
Back to top
benkasminbullock@gmail.co
*nix forums beginner


Joined: 14 May 2006
Posts: 33

PostPosted: Fri May 26, 2006 12:12 am    Post subject: Re: Problem with passing array to subroutine Reply with quote

"David Squire" <David.Squire@no.spam.from.here.au> wrote in message
news:e54ha9$fo0$1@news.ox.ac.uk...
Quote:
Ben Bullock wrote:
Change to:

sub print_table
{
my $table_ref = shift;
my @rows = @{$table_ref};

[snip]

print_table (@table);

Change to:

print_table (\@table);

Moral: it's always a good idea to pass *references* to large and complex
data structures.

Thank you. This is exactly what I wanted to know. I was trying to pass the
reference but I couldn't get the syntax right.
Back to top
benkasminbullock@gmail.co
*nix forums beginner


Joined: 14 May 2006
Posts: 33

PostPosted: Fri May 26, 2006 12:33 am    Post subject: Re: Problem with passing array to subroutine Reply with quote

<xhoster@gmail.com> wrote in message
news:20060525111402.488$2s@newsreader.com...
Quote:
Ben Bullock <benkasminbullock@gmail.com> wrote:
Can anyone explain what I'm doing wrong in the following?

Thanks for posting a working program. But with a script this large (and
ugly), you should have provided a little more exposition about what
purpose
each part served.

And I thought my humble script would be so obvious to the Perl gurus...

Quote:
Anyway,

sub print_table
{
my @rows = $_[0];

since you pass in the whole array, you need to capture the whole
array, not just the first element of it, in @rows:

my @rows = @_;

Thanks very much. I was trying to pass in a reference, but I couldn't get
the syntax right.
Back to top
Tad McClellan
*nix forums Guru


Joined: 09 Mar 2005
Posts: 1647

PostPosted: Fri May 26, 2006 3:43 am    Post subject: Re: Problem with passing array to subroutine Reply with quote

Ben Bullock <benkasminbullock@gmail.com> wrote:
Quote:
"Tad McClellan" <tadmc@augustmail.com> wrote in message
news:slrne7c7pf.ef3.tadmc@magna.augustmail.com...
Ben Bullock <benkasminbullock@gmail.com> wrote:


Quote:
while ($rt =~ s/\|(.*)//) {


Q: How many times will that loop iterate?

A: One.

A: Three? Or else why does it print three results?


Doh! I failed my own test!

Sorry.


Quote:
Anyway, as a meta-query, would it be better to post the whole code of my
program


No.


Quote:
or to post this kind of minimal script?


It is better to post a minimal script.


--
Tad McClellan SGML consulting
tadmc@augustmail.com Perl programming
Fort Worth, Texas
Back to top
Google

Back to top
Display posts from previous:   
Post new topic   Reply to topic Page 1 of 1 [12 Posts] View previous topic :: View next topic
The time now is Wed Dec 03, 2008 1:34 am | All times are GMT
navigation Forum index » Programming » Perl
Jump to:  

Similar Topics
Topic Author Forum Replies Last Post
No new posts Unknown in header problem -SOLVED- Light Speed Postfix 0 Thu Jul 03, 2008 10:40 am
No new posts problem with sending mail nuxia Postfix 0 Mon Apr 21, 2008 3:58 am
No new posts Postfix 2.3.8 Virtual problem Blotto Postfix 0 Fri Apr 04, 2008 6:11 am
No new posts Postfix sending problem for local domain remote email monkey_magix Postfix 0 Mon Sep 10, 2007 10:17 am
No new posts bounce problem murkis Postfix 0 Sun Oct 08, 2006 3:45 pm

Fighting Videos | Loans | Power Rangers | Personal Loans | Mobile Phones
Copyright © 2004-2005 DeniX Solutions SRL
 
Other DeniX Solutions sites: Unix/Linux blog |  electronics forum |  medicine forum |  science forum | 
Privacy Policy


Powered by phpBB © 2001, 2005 phpBB Group
[ Time: 0.3217s ][ Queries: 16 (0.1775s) ][ GZIP on - Debug on ]