I would like to change variables stored in a hash, but I kept receiving the error:
"Can't use the string ("SCALAR(0x30f558)") as a SCALAR ref while "strict refs" in use at - line 14.
My simplified code is as follows:
#!/usr/bin/perl
use strict;
use warnings;
my $num = 1234;
my $a = 5;
my %hash = (\$num => "value");
foreach my $key (keys %{hash}){
print "Key: $key\n";
#OPTION1: $a = $$key;
}
my $ref = \$num ;
print "Ref: $ref\n";
#OPTION2: $a = $$ref ;
print $a;
Running this prints:
Key: SCALAR(0x30f558)
Ref: SCALAR(0x30f558)
5
showing that both $key and $ref are pointing to the same variable – $num
Also, the code on OPTION1 and OPTION2 are identical if $key and $ref are the same.
When I uncomment OPTION2, $a prints out as 1234.
When I uncomment OPTION1, however, I receive the error shown above.
QUESTION:
How do I change $a to $num using the hash as I tried to do in OPTION1? And why will this not work as is?
References:
http://cpansearch.perl.org/src/CHIPS/perl5.004_05/t/pragma/strict-refs
I followed this code closely:
use strict 'refs' ;
my $fred ;
my $b = \$fred ;
my $a = $$b ;
which posed no error until I introduced the hash.
Thank you for your help.
Original Code (doesn’t work):
#User Defined - here are the defaults
my $a = 122160;
my $b = 122351;
my $c = 'string';
my $d = 15;
my $e = 123528;
#etc.
#Create variable/print statement hash
my %UserVariables = (
\$a => "A: (Default: $a): ",
\$b => "B: (Default: $b): ",
\$c => "C: (Default: $c): ",
\$d => "D: (Default: $d): ",
\$e => "E: (Default: $e): ",
);
#Allow user to change variables if desired
foreach (keys %UserVariables){
print $UserVariables{$_};
chomp (my $temp = <>);
print "$_\n";
$$_ = $temp unless ($temp eq '');
print "$temp\n" unless ($temp eq '');
};
Less efficient method that does work:
#Alternate Method without loops (not ideal)
my $temp;
print $UserVariables{\$a};
chomp ($temp = (<>));
$a= $temp unless ($temp eq '');
print $UserVariables{\$b};
chomp ($temp = (<>));
$b= $temp unless ($temp eq '');
print $UserVariables{\$c};
chomp ($temp = (<>));
$c= $temp unless ($temp eq '');
print $UserVariables{\$d};
chomp ($temp = (<>));
$d= $temp unless ($temp eq '');
print $UserVariables{\$e};
chomp ($temp = (<>));
$e= $temp unless ($temp eq '');
Perl hash keys can only be string. You don’t have reference as key, but what your reference automatically stringified to: a verbatim string “SCALAR(0x30f558)” instead. Obviously, string won’t work as reference.
You should rethink the way you store data and maybe explain in little more details what you want to do instead on focusing on how.
In your particular case illustrated by example just use plain hash for those values you want to be overridable:
…and then overwrite values in this hash.