plevine has asked for the wisdom of the Perl Monks concerning the following question:

Trying to do it right - My script uses symbolic references. I'd like to know how change it so that I'm using hard references and can use 'use strict' without errors.

The program receives a hash of hashes and then attempts to update the hash after the record has read.

my %hash=('1'=>{one=>""}, '2'=>{two=>"",zwei=>"",dos=>""}, '3'=>{three +=>"",tres=>""},'4'=>{four=>""},'5'=>{five=>""},6=>{six=>"",seis=>""}, +7=>{seven=>""}); my %subs; my $href; my $valCount=0; my $recCount=0; #get number of items foreach my $item (keys %hash) { print "count is " . (keys %{$hash{$item}}) . "\n"; $valCount+= (keys %{$hash{$item}}); } while($valCount > 0) { foreach my $id (sort keys %hash) { if(! exists $subs{$id}) { $href=$hash{$id}; foreach my $word (sort keys %$href) { next if(exists $$href{$word}{written}); $valCount--; print "$id $word\n"; $subs{$id}=""; $href->{$word}={written=>1}; last if((keys %{$hash{$id}}) > 1); } $recCount++; if($recCount == 4) { $recCount=0; %subs=(); } } } }

Replies are listed 'Best First'.
Re: desire hard ref alternative
by choroba (Cardinal) on Aug 15, 2014 at 22:36 UTC
    In this particular case, the change is easy. Instead of using $$href{$word}{written}, you can use $href->{word} = 'written', because there are no interesting values in the second level hash.
    #!/usr/bin/perl use warnings; use strict; my %hash = ( 1 => { one => q() }, 2 => { two => q(), zwei => q(), dos => q() }, 3 => { three => q(), tres => q() }, 4 => { four => q() }, 5 => { five => q() }, 6 => { six => q(), seis => q() }, 7 => { seven => q() }, ); my $valCount; for my $item (keys %hash) { my $count = keys %{ $hash{$item} }; print "count is $count\n"; $valCount += $count; } my %subs; my $recCount; while ($valCount > 0) { for my $id (sort keys %hash) { if (not exists $subs{$id}) { my $href = $hash{$id}; for my $word (sort keys %$href) { next if 'written' eq $href->{$word}; $valCount--; print "$id $word\n"; $subs{$id} = q(); $href->{$word} = 'written'; last if keys %{ $hash{$id} } > 1; } $recCount++; if ($recCount == 4) { $recCount = 0; %subs = (); } } } }

    Generally, you'd need to introduce one more layer to store the original value and the new hash:

    my %hash = ( 1 => { one => { value => 'v' }, ...
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

      Thanks! The check is in the mail! (really)

Re: desire hard ref alternative
by Anonymous Monk on Aug 15, 2014 at 22:20 UTC
    where are you using symbolic references?
      Even without reading the code, you can prepend use strict; and run it; and Perl will tell you:
      Can't use string ("") as a HASH ref while "strict refs" in use at ./3o +.pl line 25.

      So, here:

      next if(exists $$href{$word}{written});
      لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

        ok, so $$href{$word} is not a hashref , its a string... so it can't have an written key :)