Domanda

I want to make a subroutine that adds elements (keys with values) to a previously-defined hash. This subroutine is called in a loop, so the hash grows. I don’t want the returning hash to overwrite existing elements.

At the end, I would like to output the whole accumulated hash.

Right now it doesn’t print anything. The final hash looks empty, but that shouldn’t be. I’ve tried it with hash references, but it does not really work. In a short form, my code looks as follows:

sub main{
  my %hash;
  %hash=("hello"=>1); # entry for testing

  my $counter=0;
  while($counter>5){ 
    my(@var, $hash)=analyse($one, $two, \%hash);
    print ref($hash);

    # try to dereference the returning hash reference,
    # but the error msg says: its not an reference ...
    # in my file this is line 82
    %hash=%{$hash};

    $counter++;
  }

  # here trying to print the final hash
  print "hash:", map { "$_ => $hash{$_}\n" } keys %hash;
}

sub analyse{
  my $one=shift;
  my $two=shift;
  my %hash=%{shift @_};
  my @array; # gets filled some where here and will be returned later 

  # adding elements to %hash here as in 
  $hash{"j"} = 2;  #used for testing if it works

  # test here whether the key already exists or
  # otherwise add it to the hash

  return (@array, \%hash);
}

but this doesn’t work at all: the subroutine analyse receives the hash, but its returned hash reference is empty or I don’t know. At the end nothing got printed.

First it said, it's not a reference, now it says:

Can't use an undefined value as a HASH reference
    at C:/Users/workspace/Perl_projekt/Extractor.pm line 82.

Where is my mistake?

I am thankful for any advice.

È stato utile?

Soluzione

Arrays get flattened in perl, so your hashref gets slurped into @var.

Try something like this:

my ($array_ref, $hash_ref) = analyze(...)

sub analyze {
  ...
  return (\@array, \@hash);
}

Altri suggerimenti

If you pass the hash by reference (as you're doing), you needn't return it as a subroutine return value. Your manipulation of the hash in the subroutine will stick.

 my %h = ( test0 => 0 );

 foreach my $i ( 1..5 ) {
    do_something($i, \%h);
 }

 print "$k = $v\n" while ( my ($k,$v) = each %h );


 sub do_something {
   my $num = shift;
   my $hash = shift;

   $hash->{"test${num}"} = $num;  # note the use of the -> deference operator
 }

Your use of the @array inside the subroutine will need a separate question :-)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top