laziness, impatience, and hubris | |
PerlMonks |
Re: hash keyby haukex (Archbishop) |
on May 30, 2017 at 14:48 UTC ( [id://1191596]=note: print w/replies, xml ) | Need Help?? |
Just to supplement Corion's explanations, I think that part of the misunderstanding might be that only simple hash subscripts are quoted automatically. From perldata: ... a simple identifier within such curlies is forced to be a string, and likewise 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 your case, neither {"T::c"} nor {$var} are such "simple" subscripts (aka "barewords", see Identifier parsing). So they are not automatically quoted and are instead treated as Perl expressions. So if you say $var = '"T::c"', it now holds a string consisting of six characters, the first and last are the quotes, and when you say $my_hash{$var}, the hash key is that exact six-character string, including the quote characters. But the Perl expression "T::c" means a string of four characters, not including the quotes, so that is the key that gets accessed when you say $my_hash{"T::c"} or $var = "T::c"; $my_hash{$var}. To illustrate the different possibilities, here I am building a hash where all the values are the same as the keys. Note how only the simplest of identifiers are automatically quoted, and as soon as the thing inside the braces contains characters like -, ., (), ", etc. it is treated as a Perl expression, <update2> even something as seemingly simple as $hash{123abc} is no longer a simple identifier because it starts with a digit. </update2> This list contains a few very "tricky" examples that might not be easy to immediately understand (like $hash{T-b}), but don't worry about that yet - the thing to take away from this is that most special characters in hash subscripts cause them to be treated as expressions, and if you don't want that you will need to use strings instead, like $hash{"T-b"} or my $var = "T-b"; $hash{$var} = .... <update> By the way, I wrote a bit about the => operator aka "fat comma", which also autoquotes barewords on its left-hand side, here. </update>
I hope this explains how you can access your hash keys no matter whether the keys contain quotes or whatever other characters. Now, one last thing, if you have a string that contains double quotes, like '"T::c"', and you want to access a hash key without those double quotes, like $hash{"T::c"}, then I have two suggestions. First, I would look at the source that you are getting this string '"T::c"' from and see if you can change something there - often it is the result of insufficient parsing, like for example when you have a CSV file whose fields unexpectedly contain quotes, in which case using a proper parser, like Text::CSV, is the best solution. Otherwise, if this isn't the case for whatever reason, one way to remove the double quotes from the ends of the string is like this:
In Section
Seekers of Perl Wisdom
|
|