foreach loop variable is not initialised correctly for a Readonly::Scalar object
Problem Description
When Readonly::Scalar is used for a hash reference, and the referenced hash contains a key whose value is an array reference. In such a scenario running over each array member in a foreach loop and trying to match it against a regex (defined as a constant ) results in perl interpreter throwing " uninitialized value" warning for the loop variable.
perl version
perl 5, version 24, subversion 1
sample code causing error
use strict;
use warnings;
use Readonly;
use constant ID_REGEX => qr/^(_|[a-z]+)[a-zA-Z0-9-]*$/;
sub return_catenated {
my ($string, $ids) = @_;
foreach my $id (@$ids) {
my $type = $id =~ ID_REGEX; # Warning thrown at this line.
$string = $type." ".$string;
}
return $string;
}
my %hash = ("name" => "happy",
"ids" => ["id-f123456","id-a123456" ,"id-c123456"]);
my $ref = \%hash;
Readonly::Scalar my $var => $ref;
my $ids = $var->{"ids"};
my $string = "hello";
print return_catenated($string, $ids);
Observations so far
If I use the loop variable for printing or for an assigment before the regex match, Error is not seen. Consider the below snippet from the script pasted above
foreach my $id (@$ids) {
my $id1 = $id; #adding this statement does not cause the error
my $type = $id =~ ID_REGEX; # Warning thrown at this line.
$string = $type." ".$string;
}
adding the statement my $id1 = $id; does not cause the error.
Also instead of using the constant if i use the match expression directly , the error is not seen.
So if I replace the statement
my $type = $id =~ ID_REGEX; in the above snippet with
my $type = $id =~ /^(_|[a-z]+)[a-zA-Z0-9-]*$/;
the error is not seen.
This error is seen only if the hash reference is made Readonly::Scalar,. If the hash reference is passed directly(with making it Readonly::Scalar) the error is not seen.