Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Trouble Passing Array Containing Hash to Subroutine

Reply
Thread Tools

Trouble Passing Array Containing Hash to Subroutine

 
 
Scott
Guest
Posts: n/a
 
      12-05-2004
All:

I am using Perl 5.8.0 on Red Hat Linux release 9 (Shrike).
I am attempting to pass a reference to an array whose elements are a
hash. When I go to generalize my code and pass a reference to this
array to a subroutine, the results I get back are unexpected.

Here is my annotated test program:

#!/usr/bin/perl -w

#Create empty array arySTUFF.
my @arySTUFF=();

#Create hash to map 0,1,2 to data element names
# corresponding to database column names.
my %hSTUFF_VARLIST=(0=>'DATE_AUTH',
1=>'FILENAME',
2=>'CLAIMS');

#Push an anonymous hash into the array arySTUFF
# making it the first (zeroth) element of the array.
# Note that I am initializing each of the hash elements
# in case there is no data coming in from my data source
# I will have some value.
push(@arySTUFF,{DATE_AUTH => 'XXXXXXXX',
FILENAME => 'No FileName',
CLAIMS => -1});

#Initialize the three hash elements for this first array element
# and then print out the results to see if it worked.
$$arySTUFF[0]->{$hSTUFF_VARLIST{0}}="20041116";
$$arySTUFF[0]->{$hSTUFF_VARLIST{1}}="BIGDATAFILE.TXT";
$$arySTUFF[0]->{$hSTUFF_VARLIST{2}}=12345;
print "DATE_AUTH=",$$arySTUFF[0]{$hSTUFF_VARLIST{0}},"\n";
print "FILENAME=",$$arySTUFF[0]{$hSTUFF_VARLIST{1}},"\n";
print "CLAIMS=",$$arySTUFF[0]{$hSTUFF_VARLIST{2}},"\n";

#The next line shows that $$arySTUFF[0] is a HASH reference
# at some memory location.
print "ARYSTUFF[0]=",$$arySTUFF[0],"\n";
#The next line shows the actual value in the hash reference
# for FILENAME. This works.
print "ARYSTUFF[0]=>",$$arySTUFF[0]->{FILENAME},"\n";

#Pass a reference to the array arySTUFF and hash hSTUFF_VARLIST.
# Note that I have no problem with hash ref at all, just the array
ref.
print "===TRYSUB===\n";
TrySub(\@arySTUFF,\%hSTUFF_VARLIST);

#Use a subroutine to generalize the arrays and the hashes.
sub TrySub {
my @aryData = @{$_[0]};
my $hData = $_[1];
print "Num Rows==>",$#aryData+1,"\n";
#The following line show a difference HASH memory location
# than the one above.
print "ARYDATA[0]=",$aryData[0],"\n";
#The following prints out the initialization value "No Filename"
# rather than the expected BIGDATAFILE.TXT.
print "ARYDATA[0]=>",$aryData[0]->{FILENAME},"\n";

#Just in case, let's check if arySTUFF is messed up...it isn't.
print "\nCheck: Original arySTUFF is okay\n";
print "ARYSTUFF[0]=",$$arySTUFF[0],"\n";
print "ARYSTUFF[0]=>",$$arySTUFF[0]->{FILENAME},"\n";

}

exit;


Here are the results of this test program:

DATE_AUTH=20041116
FILENAME=BIGDATAFILE.TXT
CLAIMS=12345
ARYSTUFF[0]=HASH(0x80660b0)
ARYSTUFF[0]=>BIGDATAFILE.TXT
===TRYSUB===
Num Rows==>1
ARYDATA[0]=HASH(0x804ca8
ARYDATA[0]=>No FileName

Check: Original arySTUFF is okay
ARYSTUFF[0]=HASH(0x80660b0)
ARYSTUFF[0]=>BIGDATAFILE.TXT


When the subroutine prints out "No Filename", I am confused as to why
this happens. I am expecting to see BIGDATAFILE.TXT. Any help with
this would be very greatly appreciated. (I'd hate to hard code my
program when a nice subroutine would be better!)

Thanks!
Scott
 
Reply With Quote
 
 
 
 
Gunnar Hjalmarsson
Guest
Posts: n/a
 
      12-06-2004
Scott wrote:
> I am attempting to pass a reference to an array whose elements are a
> hash. When I go to generalize my code and pass a reference to this
> array to a subroutine, the results I get back are unexpected.
>
> Here is my annotated test program:
>
> #!/usr/bin/perl -w


Why not

use strict;

?? If you had had strictures enabled, you would have been able to figure
out what mistake you made.

--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl
 
Reply With Quote
 
 
 
 
Jim Keenan
Guest
Posts: n/a
 
      12-06-2004
Scott wrote:

> All:
>
> I am using Perl 5.8.0 on Red Hat Linux release 9 (Shrike).
> I am attempting to pass a reference to an array whose elements are a
> hash. When I go to generalize my code and pass a reference to this
> array to a subroutine, the results I get back are unexpected.
>
> Here is my annotated test program:
>
> #!/usr/bin/perl -w


Why haven't you used this?

use strict;

>
> #Create empty array arySTUFF.
> my @arySTUFF=();


Your choice of variable names creates unnecessary line noise. Why is
everything named some variant of 'STUFF'?
>
> #Create hash to map 0,1,2 to data element names
> # corresponding to database column names.
> my %hSTUFF_VARLIST=(0=>'DATE_AUTH',
> 1=>'FILENAME',
> 2=>'CLAIMS');


If you're using non-negative integers for the keys of a hash, you might
as well use an array instead, since arrays are automatically indexed by
non-negative integers.

I copied-and-pasted your code, ran it (it did compile), and got no
output whatsoever. So I'm not able to directly comment on your problem.
However, I *strongly* recommend that before proceeding further you get
familiar with the Data:umper module, as it is the most widely used way
to dump and examine the contents of variables, particularly multi-level
arrays and hashes such as you are using.

% perldoc Data:umper

Jim Keenan
 
Reply With Quote
 
A. Sinan Unur
Guest
Posts: n/a
 
      12-06-2004
http://www.velocityreviews.com/forums/(E-Mail Removed) (Scott) wrote in
news:(E-Mail Removed) om:

> I am attempting to pass a reference to an array whose
> elements are a hash.


I have no idea what this sentence means.

> When I go to generalize my code and pass a reference to this
> array to a subroutine, the results I get back are unexpected.


Ditto.

> Here is my annotated test program:
>
> #!/usr/bin/perl -w


use warnings;

Incidentally, you really ought to make sure you fix everything perl warns
you about before posting here. Have you read the posting guidelines for
this group?

D:\Home>perl t7.pl
Warning: Use of "ref" without parentheses is ambiguous at t7.pl line 39.
Useless use of concatenation (.) or string in void context at t7.pl line
40.

And, why do you not have

use strict;

D:\Home>perl t7.pl
Warning: Use of "ref" without parentheses is ambiguous at t7.pl line 42.
Global symbol "$arySTUFF" requires explicit package name at t7.pl line 26.
Global symbol "$arySTUFF" requires explicit package name at t7.pl line 27.
Global symbol "$arySTUFF" requires explicit package name at t7.pl line 28.
Global symbol "$arySTUFF" requires explicit package name at t7.pl line 29.
Global symbol "$arySTUFF" requires explicit package name at t7.pl line 30.
Global symbol "$arySTUFF" requires explicit package name at t7.pl line 31.
Global symbol "$arySTUFF" requires explicit package name at t7.pl line 35.
Global symbol "$arySTUFF" requires explicit package name at t7.pl line 38.
Global symbol "$arySTUFF" requires explicit package name at t7.pl line 60.
Global symbol "$arySTUFF" requires explicit package name at t7.pl line 61.
Execution of t7.pl aborted due to compilation errors.

What can I say? Isn't that obvious enough?

> #Create empty array arySTUFF.


Useless comments are worse than no comments.

> my @arySTUFF=();


Declare your variables in the smallest applicable scope.

> #Create hash to map 0,1,2 to data element names
> # corresponding to database column names.


Why?

> my %hSTUFF_VARLIST=(0=>'DATE_AUTH',
> 1=>'FILENAME',
> 2=>'CLAIMS');


Choosing the correct data structure for your problem is essential. In this
case, why use a hash when you are indexing using nonnegative integers?

> #Push an anonymous hash into the array arySTUFF
> # making it the first (zeroth) element of the array.


This amount of noise is really uncalled for and coupled with the really bad
variable names makes your code very hard to read. In case you haven't
noticed, we know that @arySTUFF is an array not because of the prefix 'ary'
but because of the @ sign in front of it. Variable names should be
descriptive of the information variables hold.

> # Note that I am initializing each of the hash elements
> # in case there is no data coming in from my data source
> # I will have some value.


Sigh! What data source?

> push(@arySTUFF,{DATE_AUTH => 'XXXXXXXX',
> FILENAME => 'No FileName',
> CLAIMS => -1});
>
> #Initialize the three hash elements for this first array element
> # and then print out the results to see if it worked.
> $$arySTUFF[0]->{$hSTUFF_VARLIST{0}}="20041116";
> $$arySTUFF[0]->{$hSTUFF_VARLIST{1}}="BIGDATAFILE.TXT";
> $$arySTUFF[0]->{$hSTUFF_VARLIST{2}}=12345;


Why $$?

> print "DATE_AUTH=",$$arySTUFF[0]{$hSTUFF_VARLIST{0}},"\n";
> print "FILENAME=",$$arySTUFF[0]{$hSTUFF_VARLIST{1}},"\n";
> print "CLAIMS=",$$arySTUFF[0]{$hSTUFF_VARLIST{2}},"\n";


This makes me think, what's up with %hSTUFF_VARLIST?

Also, please use

Data:umper

for this purpose.

> #The next line shows that $$arySTUFF[0] is a HASH reference
> # at some memory location.
> print "ARYSTUFF[0]=",$$arySTUFF[0],"\n";
> #The next line shows the actual value in the hash reference
> # for FILENAME. This works.
> print "ARYSTUFF[0]=>",$$arySTUFF[0]->{FILENAME},"\n";
>
> #Pass a reference to the array arySTUFF and hash hSTUFF_VARLIST.
> # Note that I have no problem with hash ref at all, just the array
> ref.
> print "===TRYSUB===\n";
> TrySub(\@arySTUFF,\%hSTUFF_VARLIST);
>
> #Use a subroutine to generalize the arrays and the hashes.
> sub TrySub {
> my @aryData = @{$_[0]};
> my $hData = $_[1];
> print "Num Rows==>",$#aryData+1,"\n";


There is no need for $#aryData+1. Impose scalar context on @aryData to get
the number of elements in @aryData.

> #The following line show a difference HASH memory location
> # than the one above.
> print "ARYDATA[0]=",$aryData[0],"\n";
> #The following prints out the initialization value "No Filename"
> # rather than the expected BIGDATAFILE.TXT.
> print "ARYDATA[0]=>",$aryData[0]->{FILENAME},"\n";
>
> #Just in case, let's check if arySTUFF is messed up...it isn't.
> print "\nCheck: Original arySTUFF is okay\n";
> print "ARYSTUFF[0]=",$$arySTUFF[0],"\n";
> print "ARYSTUFF[0]=>",$$arySTUFF[0]->{FILENAME},"\n";
>
> }


My head hurts!

> When the subroutine prints out "No Filename", I am confused as to why
> this happens. I am expecting to see BIGDATAFILE.TXT. Any help with
> this would be very greatly appreciated. (I'd hate to hard code my
> program when a nice subroutine would be better!)


Please read the posting guidelines for this group. This document is posted
here regularly or you can find it on the WWW at
http://mail.augustmail.com/~tadmc/cl...uidelines.text

I have a very hard time understanding why you are doing what you are doing.

#!/usr/bin/perl

use strict;
use warnings;


my @columns = qw(DATE_ATUH FILENAME CLAIMS);

my @claims;

# I think the line below would be a maintainence nightmare

push @claims, {
$columns[0] => '20041116',
$columns[1] => 'BIGDATAFILE.TXT',
$columns[2] => 12345,
};

print TrySub(claims => \@claims, columns => \@columns);

sub TrySub {
my %args = @_;
for my $claim (@{ $args{claims} }) {
for my $column (@{ $args{columns} }) {
print "$column = $claim->{$column}\n";
}
}
}


Sinan.
 
Reply With Quote
 
Gunnar Hjalmarsson
Guest
Posts: n/a
 
      12-06-2004
Jim Keenan wrote:
> I copied-and-pasted your code, ran it (it did compile), and got no
> output whatsoever.


Funny. It sure doesn't compile for me with strictures enabled. This is
the first line where Perl complains:

$$arySTUFF[0]->{$hSTUFF_VARLIST{0}}="20041116";

The first '$' character should not be there, since the declared variable
is the array @arySTUFF.

Etc., etc.

--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl
 
Reply With Quote
 
A. Sinan Unur
Guest
Posts: n/a
 
      12-06-2004
"A. Sinan Unur" <(E-Mail Removed)> wrote in
news:Xns95B6C6FC57938asu1cornelledu@132.236.56.8:

> D:\Home>perl t7.pl
> Warning: Use of "ref" without parentheses is ambiguous at t7.pl line 39.
> Useless use of concatenation (.) or string in void context at t7.pl line
> 40.


The warnings above are due to comments wrapping in my editor.

Sinan

 
Reply With Quote
 
Jim Keenan
Guest
Posts: n/a
 
      12-06-2004
Gunnar Hjalmarsson wrote:

> Jim Keenan wrote:
>
>> I copied-and-pasted your code, ran it (it did compile), and got no
>> output whatsoever.

>


I re-tried this, saving the code to file in a different way. This time
I did get output, albeit with warnings.

>
> Funny. It sure doesn't compile for me with strictures enabled. This is
> the first line where Perl complains:
>


I tried it first verbatim, i.e., without strictures.
 
Reply With Quote
 
Michael Erskine
Guest
Posts: n/a
 
      12-06-2004
Jim Keenan wrote:

> If you're using non-negative integers for the keys of a hash, you might
> as well use an array instead, since arrays are automatically indexed by
> non-negative integers.


Not if your non-negative integer keys are non-contiguous -- you fall foul of
deriving too much specific information from this limited context in your
tirade of poor-programming accusations.

Love,
Bunky
 
Reply With Quote
 
slhecht@attglobal.net
Guest
Posts: n/a
 
      12-06-2004
As (violently) suggested, I added "use strict;" and was able to
determine the problem. Thanks for the suggestions...I will try to be
much more careful in my posts in the future...sorry for any trouble...

 
Reply With Quote
 
slhecht@attglobal.net
Guest
Posts: n/a
 
      12-06-2004
As (violently) suggested, I added "use strict;" and was able to
determine the problem. Thanks for the suggestions...I will try to be
much more careful in my posts in the future...sorry for any trouble...

 
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
hash of hash of hash of hash in c++ rp C++ 1 11-10-2011 04:45 PM
Hash#select returns an array but Hash#reject returns a hash... Srijayanth Sridhar Ruby 19 07-02-2008 12:49 PM
use one subroutine's variable value in another subroutine inside a module. king Perl Misc 5 04-29-2007 06:39 AM
"too many arguments" passing hash reference to subroutine Dean Perl Misc 3 10-06-2006 11:55 AM
Options for passing Hash to a subroutine. chung.ley@amd.com Perl 6 04-04-2005 04:47 AM



Advertisments