Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Pass a Hash of Arrays to a function? 3

Status
Not open for further replies.

bitwise

Programmer
Mar 15, 2001
269
US
Hi, I need to pass a scalar and a hash of arrays to a function. I've tried several things without success. I thought it might be:

myFunction($scalar, \%hash);

...

sub myFunction {
my $scalarVal = shift(@_);
my %hashVal = %@_;

...
}

This doesn't work. Does anyone have any thoughts? Keep in mind this is a hash of arrays, and I am using "use strict;".

Thanks,
-bitwise
 
This should do:

$scalar = 'scalarparameter';
%hash=(this=>'that');
myFunction($scalar, %hash);

sub myFunction {

my ($scalarVal) = shift;

my %hashVal = (@_);
print $scalarVal;
print '\n';
print $hashVal{this};

Cheers
}
haunter@battlestrata.com
 
When sending arrays and hashes to subroutines, it's often better to pass by reference, as you originally had. Yes, this means you can change the original, but it allows more flexibility in how you can pass it. Haunter's method works only if you pass only one hash or array to a sub, and the hash or array is the last argument. Otherwise there's no way to tell when one argument ends and the next begins. Also, I'd assume that it uses less memory, not making a copy of the arguments, but I don't know how perl deals with that. Consider the following:
Code:
use strict;
use warnings;

my $scalar = 'asdf';
my @array = (0,1,2,3);
my %hash = ('qwerty' => 'dvorak');

#\%hash sends a reference to a hash, stored in a single scalar
myFunction(\%hash, $scalar, \@array);

sub myFunction {
	#shift works off @_ by default, so you don't need to specify it
	my $hashRef = shift;
	my $scalarVal = shift(@_);
	my $arrayRef = shift;
	
	#check if the values shifted are references
	return unless(ref $hashRef && ref $arrayRef);
	
	#dereference the references back into a hash and array
	my %hashVal = %$hashRef;
	my @arrayVal = @$arrayRef;
	
	print "Hash{qwerty}: $hashVal{'qwerty'}\tScalar: $scalarVal\tArray[1]: $arrayVal[1]\n";
}
----------------------------------------------------------------------------------
...but I'm just a C man trying to see the light
 
Thanks icrf I do like that method better. The hash is quite large and saving the time on a copy operation would probably be a good thing. That is what I initially wanted, but couldn't get it to work out. I was close.

Thanks,
-bitwise
 
One more thing, if it is saving memory and copy time by passing by reference, then the dereferencing lines negates that and makes a copy anyway (I'm pretty sure it does). May want to consider removing the two like this:
Code:
my %hashVal = %$hashRef;
and just using them as references, like this:
[tt]
print $hashRef[red]->[/red]{'qwerty'};
[/tt]
It's not quite as pretty in code, but it wouldn't be copying the potentially huge data structures. It dereferences each element one at a time (likely destroying or reusing the memorty) instead of the whole structure at once.

----------------------------------------------------------------------------------
...but I'm just a C man trying to see the light
 
Hmm, I tried that but it actually slowed it down by a bit. However, I am running a loop like this:

foreach my $key (keys(%hash)) {
...
}

So, I still had to say:

foreach my $key (keys(%$hashRef)) {
...
}

I think that still would make a copy then. Using the $hashRef variable, is there a way to use the keys() function, b/c you need to pass a hash to that function.

Thanks,
-bitwise
 
Well, saying %$hashRef uses the reference and the original memory. When you set something equal to that, it copies it all over into the new hash. It should work fine. I'm not sure why it would have any slowdown. If it's a serious timing issue, you might want to look into something like Benchmark::Timer and test the snippet.

----------------------------------------------------------------------------------
...but I'm just a C man trying to see the light
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top