Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Need help passing arrays by reference pls.

Reply
Thread Tools

Need help passing arrays by reference pls.

 
 
G Klinedinst
Guest
Posts: n/a
 
      02-06-2004
Hi all. I have a question I have been pulling my hair out all day
over. Can someone tell me what is happening in the following code. The
first print statements create the results I expect. The subroutines
statments print arrays with 1 element but not data in [0]. What gives?
I am passing by reference and then dereferencing in the sub. Can you
point me towards what I am missing? I have looked at the perlfaqs and
read the perldocs on references but it I can't find what I am looking
for. It could also be my sleep deprived mind is seeing it but not
grokking it. TIA.

-Greg

***********CODE****************
#!/usr/local/bin/perl

use strict;
use warnings;

my @arr1;
my @arr2;

$arr1[0] = 1;

print( $arr1[0] . ":" . scalar( @arr1 ) . "\n" );
print( $arr2[0] . ":" . scalar( @arr2 ) . "\n" );
print( "\n\n" );

test( \@arr1, \@arr2 );

sub test
{
my @subArr1 = @$_[0];
my @subArr2 = @$_[1];

print( $subArr1[0] . ":" . scalar( @subArr1 ) . "\n" );
print( $subArr2[0] . ":" . scalar( @subArr2 ) . "\n" );
}
**************/CODE***********

**************OUTPUT*********
1:1
Use of uninitialized value in concatenation (.) or string at
../arrays.pl
line 12.
:0


Use of uninitialized value in concatenation (.) or string at
../arrays.pl
line 22.
:1
Use of uninitialized value in concatenation (.) or string at
../arrays.pl
line 23.
:1
*************/OUTPUT**********
 
Reply With Quote
 
 
 
 
Walter Roberson
Guest
Posts: n/a
 
      02-06-2004
In article <(E-Mail Removed) >,
G Klinedinst <(E-Mail Removed)> wrote:
:Hi all. I have a question I have been pulling my hair out all day
ver. Can someone tell me what is happening in the following code.

:test( \@arr1, \@arr2 );

:sub test
:{
: my @subArr1 = @$_[0];
: my @subArr2 = @$_[1];

Looks like you have a precidence problem. @$_[0] is {@{$_}}[0]
Your code will work if you use

my @subArr1 = @{$_[0]};
my @subArr2 = @{$_[1]};


I would, though, recommend using prototypes and declaring sub test
before it is used:

sub test( \@\@ ) {
my @subArr1 = @{$_[0]};
my @subArr2 = @{$_[1]};
# ...
}

test @arr1, @arr2;


Notice there that you do NOT explicitly \ the arrays as you pass them in.


Personally, I wouldn't take a copy of the array in the sub unless
I had a reason to. I would use something akin to

sub test( \@\@ ) {
my ($subArr1_ref, $subArr2_ref) = @_;
print $subArr1_ref->[0] . ':' . scalar( @$subArr1_ref ) . "\n";
print $subArr2_ref->[0] . ':' . scalar( @$subArr2_ref ) . "\n";
}
--
"There are three kinds of lies: lies, damn lies, and statistics."
-- not Twain, perhaps Disraeli, first quoted by Leonard Courtney
 
Reply With Quote
 
 
 
 
A. Sinan Unur
Guest
Posts: n/a
 
      02-06-2004
http://www.velocityreviews.com/forums/(E-Mail Removed) (G Klinedinst) wrote in
news:(E-Mail Removed) om:

> Hi all. I have a question I have been pulling my hair out all day
> over. Can someone tell me what is happening in the following code. The
> first print statements create the results I expect. The subroutines
> statments print arrays with 1 element but not data in [0]. What gives?
> I am passing by reference and then dereferencing in the sub. Can you
> point me towards what I am missing? I have looked at the perlfaqs and
> read the perldocs on references but it I can't find what I am looking
> for. It could also be my sleep deprived mind is seeing it but not
> grokking it. TIA.
>
> -Greg
>
> ***********CODE****************
> #!/usr/local/bin/perl
>
> use strict;
> use warnings;
>
> my @arr1;
> my @arr2;
>
> $arr1[0] = 1;
>
> print( $arr1[0] . ":" . scalar( @arr1 ) . "\n" );
> print( $arr2[0] . ":" . scalar( @arr2 ) . "\n" );
> print( "\n\n" );
>
> test( \@arr1, \@arr2 );
>
> sub test
> {
> my @subArr1 = @$_[0];
> my @subArr2 = @$_[1];


Life would be much easier if you did:

#! perl

use strict;
use warnings;

my @arr1 = (1, 2, 3);
my @arr2 = (4, 5, 6);

$arr1[0] = 1;

print $arr1[0], ':', scalar @arr1, "\n" ;
print $arr2[0], ':', scalar @arr2, "\n" ;

# You should avoid the unnecessary concatenations you had in your code.

print "\n\n" ;

test(\@arr1, \@arr2);

sub test {
my ($subArr1, $subArr2) = @_;

print $subArr1->[0], ':', scalar @{$subArr1}, "\n" ;
print $subArr2->[0], ':', scalar @{$subArr2}, "\n" ;
}

--
A. Sinan Unur
(E-Mail Removed) (reverse each component for email address)
 
Reply With Quote
 
G Klinedinst
Guest
Posts: n/a
 
      02-06-2004
http://www.velocityreviews.com/forums/(E-Mail Removed)-cnrc.gc.ca (Walter Roberson) wrote in message news:

> Looks like you have a precidence problem. @$_[0] is {@{$_}}[0]
> Your code will work if you use
>
> my @subArr1 = @{$_[0]};
> my @subArr2 = @{$_[1]};


Thanks, that worked perfectly. I see what I was doing now.

> I would, though, recommend using prototypes and declaring sub test
> before it is used:
>
> sub test( \@\@ ) {
> my @subArr1 = @{$_[0]};
> my @subArr2 = @{$_[1]};
> # ...
> }
>
> test @arr1, @arr2;
>
> Notice there that you do NOT explicitly \ the arrays as you pass them in.


Yep, I am just not sure why. I will need to study the docs this
weekend and figure out what you are doing here.


> Personally, I wouldn't take a copy of the array in the sub unless
> I had a reason to. I would use something akin to
>
> sub test( \@\@ ) {
> my ($subArr1_ref, $subArr2_ref) = @_;
> print $subArr1_ref->[0] . ':' . scalar( @$subArr1_ref ) . "\n";
> print $subArr2_ref->[0] . ':' . scalar( @$subArr2_ref ) . "\n";
> }


Makes sense. The reason I am making a local copy is that I am going to
be iterating through them(using a for loop). With your syntax I'm not
sure how I would go about that. For example I will be doing something
like this:

for my $a ( @subArr1 ) {
print $a;
}

If I can figure out how to do that using the references, like you are
using I will do that otherwise I will have to make a local copy.
Thanks again.


-Greg
 
Reply With Quote
 
Walter Roberson
Guest
Posts: n/a
 
      02-06-2004
In article <(E-Mail Removed) >,
G Klinedinst <(E-Mail Removed)> wrote:
:Makes sense. The reason I am making a local copy is that I am going to
:be iterating through them(using a for loop). With your syntax I'm not
:sure how I would go about that. For example I will be doing something
:like this:

:for my $a ( @subArr1 ) {
: print $a;
:}

:If I can figure out how to do that using the references, like you are
:using I will do that otherwise I will have to make a local copy.

print $_ foreach @$subArr1_ref

Similarily,

print "$_: $hash_ref->{$_}\n" foreach (keys %$hash_ref);

print $$scalar_ref, "\n"
--
Warning: potentially contains traces of nuts.
 
Reply With Quote
 
G Klinedinst
Guest
Posts: n/a
 
      02-06-2004
> Life would be much easier if you did:
>
> #! perl
>
> use strict;
> use warnings;
>
> my @arr1 = (1, 2, 3);
> my @arr2 = (4, 5, 6);
>
> $arr1[0] = 1;
>
> print $arr1[0], ':', scalar @arr1, "\n" ;
> print $arr2[0], ':', scalar @arr2, "\n" ;
>


Unfortunately the arrays hold an index to another array, which
basically tells which input fields were filled out, so some of the
arrays are going to be empty(due to the user not entering any data at
that position).


> # You should avoid the unnecessary concatenations you had in your code.
>
> print "\n\n" ;
>
> test(\@arr1, \@arr2);
>
> sub test {
> my ($subArr1, $subArr2) = @_;
>
> print $subArr1->[0], ':', scalar @{$subArr1}, "\n" ;
> print $subArr2->[0], ':', scalar @{$subArr2}, "\n" ;
> }


Why is that? Are the commas implemented faster, or just for
readability? Just curious. It's a habit I picked up from Java so now
even my Perl code looks like that. It's hard to break coding habits
once you get into them. Thanks for your help, and I hope things are
starting to warm up there in Ithaca for you.

-Greg
 
Reply With Quote
 
Walter Roberson
Guest
Posts: n/a
 
      02-06-2004
In article <(E-Mail Removed) >,
G Klinedinst <(E-Mail Removed)> wrote:
:> # You should avoid the unnecessary concatenations you had in your code.

:Why is that? Are the commas implemented faster, or just for
:readability?

Commas in print's are converted into concatenation internally, so both
have the same execution speed.

Sometimes, though, if you use concatenation, you can end up
with unexpected results because of precidence issues. Just a couple
of days ago, I had something of the form

print Operation Argument . Somestring

and Operation was being applied to Argument . Somestring
instead of Operation Argument being computed and Somestring being
concatenated on the end. My fault for not thinking about precidences.
Changing to , instead of . fixed the code.
--
Will you ask your master if he wants to join my court at Camelot?!
 
Reply With Quote
 
Tad McClellan
Guest
Posts: n/a
 
      02-06-2004
G Klinedinst <(E-Mail Removed)> wrote:

> for my $a ( @subArr1 ) {


> If I can figure out how to do that using the references, like you are
> using I will do that



Apply "Use Rule 1" from perlreftut.pod:

for my $a ( @subArr1 ) { # pretend it is a regular array

for my $a ( @{ } ) { # replace the array _name_ with a block...

for my $a ( @{ $subArr1_ref } ) { # ... that returns a ref to an array

(and in this case you can drop the block's curlies)


--
Tad McClellan SGML consulting
(E-Mail Removed) Perl programming
Fort Worth, Texas
 
Reply With Quote
 
ko
Guest
Posts: n/a
 
      02-07-2004
Walter Roberson wrote:

> In article <(E-Mail Removed) >,
> G Klinedinst <(E-Mail Removed)> wrote:
> :> # You should avoid the unnecessary concatenations you had in your code.
>
> :Why is that? Are the commas implemented faster, or just for
> :readability?
>
> Commas in print's are converted into concatenation internally, so both
> have the same execution speed.


Got a question about the paragraph above ...

[snip]

Remember reading somewhere that there is a difference between the two, so I
tried this:

bash-2.05b$ cat bench && bench
#!/usr/bin/perl -w
use strict;
use Benchmark;

my $str = 'x' x 100_000;
my $null = ($^O !~ /win/i) ? '/dev/null' : 'nul';
open(NULL, ">$null") or die $!;

timethese(10_000, {
****commas*=>*sub*{print*NULL*$str,*$str,*$str,*$str},
****concat*=>*sub*{print*NULL*$str*.*$str*.*$str*.*$str}
});

__END__
Benchmark: timing 10000 iterations of commas, concat...
commas:**3*wallclock*secs*(*0.67*usr*+**1.71*sys*=**2.38*CPU)
@ 4196.72/s (n=10000)

concat:**6*wallclock*secs*(*3.88*usr*+**1.70*sys*=**5.58*CPU)
@ 1792.72/s (n=10000)

Please correct the usage if I made a mistake - rarely use Benchmark, as I
still have a lot to learn and am trying to concentrate on writing readable
good code versus writing fast code. But I would like to understand why
there is a speed difference - is it actually the case that 'Commas in
print's are converted into concatenation internally'. Is this even
something to be concerned about?

thanks in advance - keith
 
Reply With Quote
 
Walter Roberson
Guest
Posts: n/a
 
      02-07-2004
In article <c01ncm$rtq$(E-Mail Removed)>,
ko <(E-Mail Removed)> wrote:
:Walter Roberson wrote:
:> Commas in print's are converted into concatenation internally, so both
:> have the same execution speed.

:Got a question about the paragraph above ...

You think I can find the part of the documentation I was thinking of?
No....
--
Those were borogoves and the momerathsoutgrabe completely mimsy.
 
Reply With Quote
 
 
 
Reply

Thread Tools

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 On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Multidimensional arrays and arrays of arrays Philipp Java 21 01-20-2009 08:33 AM
Functions, arrays, structs and passing by reference S. C Programming 7 05-12-2008 07:41 AM
simple prob passing a reference of arrays to a func. MC felon C++ 5 02-19-2008 04:31 PM
Re: Problem with passing dynamic arrays by reference thomas.christmann@online.de C Programming 1 09-01-2004 09:30 AM
Problem with passing dynamic arrays by reference Thomas Christmann C Programming 3 08-31-2004 05:58 PM



Advertisments