Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use a Perl hash key that has a literal dot?

Tags:

hash

perl

I have a hash in Perl which has been dumped into from some legacy code the name of the key has now changed from simply reqHdrs to reqHdrs.bla

$rec->{reqHdrs.bla}

My problem is now I cant seem to access this field from the hash any ideas? The following is my error

Download Script Output: Bareword "reqHdrs" not allowed while "strict subs" in use
like image 954
wmitchell Avatar asked Apr 15 '10 17:04

wmitchell


People also ask

How can we access hash elements in Perl?

Perl Hash Accessing To access single element of hash, ($) sign is used before the variable name. And then key element is written inside {} braces.

How do I iterate through a hash in Perl?

Answer: There are at least two ways to loop over all the elements in a Perl hash. You can use either (a) a Perl foreach loop, or (b) a Perl while loop with the each function. I find the Perl foreach syntax easier to remember, but the solution with the while loop and the each function is preferred for larger hashes.

How do you check if a value exists in a hash Perl?

The exists() function in Perl is used to check whether an element in an given array or hash exists or not. This function returns 1 if the desired element is present in the given array or hash else returns 0.

How do you call a hash in Perl?

Hash variables are preceded by a percent (%) sign. To refer to a single element of a hash, you will use the hash variable name preceded by a "$" sign and followed by the "key" associated with the value in curly brackets..


2 Answers

As described in perldoc perldata:

...An identifier within such curlies is forced to be a string, as is any simple identifier within a hash subscript. Neither need quoting. Our earlier example, $days{'Feb'} can be written as $days{Feb} and the quotes will be assumed automatically. But anything more complicated in the subscript will be interpreted as an expression. This means for example that $version{2.0}++ is equivalent to $version{2}++, not to $version{'2.0'}++.

In general, if you have a hash key with a character outside the [A-Za-z0-9_] range, use quotes (either single or double) inside the braces. As with normal strings, contents in double quotes will be parsed for any contained variables, while single quoted strings are taken literally:

use strict; use warnings;
use Data::Dumper;
my $x = 1;
my %hash = (
    bare_string => 'hi there',
    "not a bare string" => 'yup',
);
$hash{'$x'} = 'foo';
$hash{"$x"} = 'bar';
print Dumper(\%hash);

prints:

$VAR1 = {
      'bare_string' => 'hi there',
      'not a bare string' => 'yup',
      '$x' => 'foo'
      '1' => 'bar',
    };
like image 89
Ether Avatar answered Sep 20 '22 14:09

Ether


According to perldoc perldata that when an identifier is used within curlies, such as when accessing a hash value via a key, that identifier is assumed to be a string and is treated as such. Quotes will be assumed automatically, however, anything more complicated can be interpreted.

From perldata

In fact, an identifier within such curlies is forced to be a string, as is any simple identifier within a hash subscript. Neither need quoting. Our earlier example, $days{'Feb'} can be written as $days{Feb} and the quotes will be assumed automatically. But anything more complicated in the subscript will be interpreted as an expression. This means for example that $version{2.0}++ is equivalent to $version{2}++ , not to $version{'2.0'}++ .

Since the . is used for string concatenation, the interpreter I'm guessing is trying to concat those two strings together. Regardless it's always better to just use quotes to make it explicit, and if you have strict on it will probably throw a "bareword not allowed" error.

The solution to your problem:

$rec->{'reqHdrs.bla'}
like image 42
Logan Avatar answered Sep 19 '22 14:09

Logan