0

I have an array of strings that I want to use in a loop and then call later as names of a hash. I wrote a test file to play around with it, but I can't get it to work no matter how hard I am trying. It keeps giving me "can't use string as a hash ref while strict refs is in use". I can turn off strict refs, but then the code simply skips those lines and doesn't do what I want. Is there any way to evaluate a variable that contains a string and then pipe it to the name of a hash?

Example code:

#usr/bin/perl
use strict;

my %combined = ();
my %highmut = ();
$combined{'a'} = 1;
$combined{'b'} = 2;
$highmut{'c'} = 3;
$highmut{'d'} = 4;
my @counts = ('combined', 'highmut');
foreach my $count (@counts) {
  my $file = $count . '.txt';
  open(my $random, ">>", $file);
  foreach my $key (keys %{$count}) {
    print $random "key: $key \t %{$count{$key}} \n";
    close($random);
  }
}

Specifically, the issues are with %{$count} and %{$count{$key}} in the last few lines.

What I want is to evaluate $count (as say combined) and then feed it to use as hash name (%combined).

Is there any way to do this?

Thanks

user3412393
  • 105
  • 1
  • 10

2 Answers2

3

You can, but it's a bad idea. Consider using a multidimensional data structure instead.

my %data = ( combined => { a => 1,
                           b => 2,
                         },
             highmut => { c => 3,
                          d => 4,
                        },
           );
foreach my $count (keys %data) {
  my $file = $count . '.txt';
  open(my $random, ">>", $file);
  foreach my $key (keys %{$data{$count}}) {
    print $random "key: $key \t $data{$count}{$key} \n";
  }
  close($random);
}

Note: you also had a bug in your program flow. You open a file based on the count type, loop over your keys, write the first one, close the file, and continue looping with no filehandle open to write to for subsequent keys. I therefore moved your close out of the iteration over keys.

Further reading:

http://perldoc.perl.org/perlfaq7.html#How-can-I-use-a-variable-as-a-variable-name%3f

perl variable substitution in variable name

In Perl, how can I use a string as a variable name?

Community
  • 1
  • 1
Oesor
  • 6,632
  • 2
  • 29
  • 56
  • Also, note you have a bug in your program flow I didn't address. You open a file based on the count type, loop over your keys, write the first one, close the file, and continue looping with no filehandle open to write to for subsequent keys. You should move your close out of the iteration over keys. – Oesor May 27 '14 at 19:46
1

Using variable strings to access named hashes is a bad idea for all kinds of maintainability and spooky-action-at-a-distance reasons. That's why use strict 'refs' doesn't let you do it on purpose or by accident. If that's what you really want to do, disable strict refs:

foreach my $count (@counts) {
  my $file = $count . '.txt';
  open(my $random, ">>", $file);
  no strict 'refs';
  foreach my $key (keys %{$count}) {
    ...
mob
  • 117,087
  • 18
  • 149
  • 283