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 gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Passing hashes into subroutines

Status
Not open for further replies.

dooley28

Programmer
Jan 3, 2008
23
IE
Hi,

I'm trying to pass a hash into a subroutine a few times.
When I pass the hash in I use
$ref_to_wf=\%wordswithfreq;
then pass the $ref_to_wf to the subroutine.

In the subroutine I set the reference to $answerarray.
When I want to modify a value in the hash, say

$answerarray->{$temp}++;


It works fine, but when I want to add a new value in the hash it will add the value, but not what its equal to.
For example:
$temp="NewVal"
$answerarray{$temp}=1;

When the subroutine is called again it will see
$answerarray{"NewVal"} as being 0.

Can anyone tell me what I'm doing wrong?

Thanks
 
For one:

Code:
$answerarray->{$temp}++;
$answerarray{$temp}=1;

These aren't the same. The first one is a hash reference and the other one is just a hash.

i.e.
Code:
my $hashref = {}; # curly brackets
my %hash = (); # parenthesis

Make sure your syntax is consistent with what kind of hash you're working with.

-------------
Cuvou.com | My personal homepage
Project Fearless | My web blog
 
I see what you mean but, when I pass an empty
hash reference into the subroutine and set it to
$answerarray, when I use:

$answerarray->{$temp}=1;

the hash its referencing is never set.


When I use this

$answerarray{$temp}=1;

the key is at least set, the value isn't however.
 
Can we see some actual code. A small sample of the data would be good too.

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
%wordswithfreq;

while($record = $sth2->FetchRow) {

$ref_to_wf=\%wordswithfreq;
wordsandfreq($ref_to_wf,\@myArray,\$totalqwords);

}

sub wordsandfreq{
my ($answerarray, $records, $totalqw ) = @_;
@temprecs = @$records;
foreach $temp (@temprecs){
$found=0;
$$totalqw++;
while(($word,$freq) = each(%answerarray)){
if($temp eq $word){
$found=1;
$answerarray->{$temp}++;
}
}
if($found == 0){
$answerarray->{$temp}=1;
print "Adding $temp to hash<br />";
}

}
}

The hash keys are basically words and the data is the frequency at which they occur.

So: Hi -> 7
Bye -> 8
 
Well, this line is certainly wrong:

while(($word,$freq) = each(%answerarray)){

if you had 'strict' and 'warnings' on you would have gotten an error alerting you to that problem. This is a bit odd, you pass a reference to a scalar:

\$totalqwords

just pass the scalar, there is no need to pass a reference unless maybe the string is gigantic.

Maybe I am missing something but this makes no sense to me:

Code:
while($record = $sth2->FetchRow) {

    $ref_to_wf=\%wordswithfreq;
    wordsandfreq($ref_to_wf,\@myArray,\$totalqwords);

}

You aren't doing anything with $record, whats the point of the loop?



------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
Kevin,

I'm not sure what you find wrong with this line.

while(($word,$freq) = each(%answerarray)){

But it works for me.


When I pass in the scalar $totalqwords, not a reference the value stays at 0 when I increment it in the subroutine.


while($record = $sth2->FetchRow) {

$ref_to_wf=\%wordswithfreq;
wordsandfreq($ref_to_wf,\@myArray,\$totalqwords);

}

This while loop is doing more than whats written here, it gets certain values, I only wrote this part as the rest really isn't needed for my problem, that I can't add values to my hash reference.

$answerarray->{$temp}=1;


 
it should be:

Code:
while(($word,$freq) = each([b]%{$answerarray}[/b])){


that way you are processing the hash you passed as a reference to the function. I'm a bit surprised your code does anything, is there another hash named %answerarray? There has to be something in the hash for the "while/each" construct to loop through.

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
It can't be said enough times: start using "strict" and "warnings". Your code could eventually "melt" and you may not be able to find the bugs unless you are using "strict".

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 

Yeah I really should have gone with strict, but the script wasn't going to be that long, so I was a bit lazy. Regretting it now. :p

Cheers for spotting that, never noticed I wasn't processing a reference, probably because for some reason the code was cycling through a working hash and I never saw the problem.
I can't honestly tell you why that code worked?? Could have been because I was adding to the hash using:
$answerarray{$temp}=1;

But shouldn't this have only created a local copy?
When I called the subroutine again,
while(($word,$freq) = each(%answerarray)){
might have been accessing this local copy.

Anyway not to worry changing the while loop condition seems to have worked perfectly. Thanks for that Kevin.

 
I think I see whats going on:

Code:
sub wordsandfreq{
    my ($answerarray, $records, $totalqw ) = @_;
    @temprecs = @$records;
        foreach $temp (@temprecs){
        $found=0;[red]<--- $found equals 0[/red]
                $$totalqw++;
        while(($word,$freq) = each(%answerarray)){
            if($temp eq $word){[red]<--- this returns false[/red]
                $found=1;[red]<--- this never gets done[/red]
                $answerarray->{$temp}++;[red]<--- this never gets done[/red]
            }
        }
        if($found == 0){[red]<--- $found is still 0[/red] 
            $answerarray->{$temp}=1;[red]<--- here you add $temp to the hash[/red]
            print "Adding $temp to hash<br />";
        }
        
    }
}

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top