Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Quoting hash keys

by Bod (Parson)
on Nov 09, 2021 at 00:11 UTC ( [id://11138587]=perlquestion: print w/replies, xml ) Need Help??

Bod has asked for the wisdom of the Perl Monks concerning the following question:

This follows on from Indirect Object Syntax but it is a different question so it gets its own place!

In doing some of the reading that came out from Indirect Object Syntax, especially this on SO from ikegami, I have noticed that often (but not always) hash keys are not quoted literals but barewords. Given the potential for confusion that has been shown from Indirect Object Syntax, it seems that this is another place where confusion could arise.

I have noticed this before but never really thought anything of it.

my $value = $hash{ key };
I never write it like that. I always quote it unless the key is non-constant.
my $value = $hash{'key'}; my $value = $hash{ $key_value }; my $value = $hash{"st_$id"};

Is there a difference between $hash{ key } and $hash{'key'}?

Replies are listed 'Best First'.
Re: Quoting hash keys
by eyepopslikeamosquito (Archbishop) on Nov 09, 2021 at 06:44 UTC

    Bod, broader than just hashes, I encourage you to spend considerable time studying and thinking about cool ways to use Perl's many and varied ways of quoting! Time well spent. At least, this is one area where I've found Perl to be (easily) the most enjoyable language I've ever used. Perl's heredocs with variable interpolation, for example, I've found to be a joy compared to wrestling with Python's ugly triple-quoted multi-line strings.

    Some examples from PBP Chapter 4 (Values and Expressions), will hopefully give you a feel for where I'm coming from.

    While I tend to favour the q{form-of-quoting} by default, for example:

    my $publisher = q{O'Reilly};

    PBP gives an example showcasing how Perl allowing you to choose a different delimiter can clarify the code (by eliminating ugly escaping), making it easier to understand at a glance:

    my $title = q[Perl Best Practices]; my $publisher = q[O'Reilly]; my $end_of_block = q[}]; my $closing_delim = q['}]; my $citation = qq[$title ($publisher)];

    The fat-comma is also worthy of study. Conway, for example, finds this version more pleasing to the eye:

    %default_service_record = ( name => '<unknown>', rank => 'Recruit', serial => undef, unit => ['Training platoon'], duty => ['Basic training'], );
    than this one:
    %default_service_record = ( 'name', '<unknown>', 'rank', 'Recruit', 'serial', undef, 'unit', ['Training platoon'], 'duty', ['Basic training'], );

    References

      The fat-comma is also worthy of study.

      Yes, this is something I use a great deal.
      However, I pretty much always quote the LHS to aid clarity despite knowing that it is not necessary for alphanumeric strings.

        I pretty much always quote the LHS to aid clarity

        I pretty much always leave the LHS bare to aid clarity. If I see an alphanumeric string quoted before a fat comma it means I have to pause and wonder why the author did that just in case there is something that I might have missed on first glance. Avoiding the quoting effectively removes the question of why it is quoted.


        🦛

Re: Quoting hash keys
by haukex (Archbishop) on Nov 09, 2021 at 08:41 UTC
    Given the potential for confusion that has been shown from Indirect Object Syntax, it seems that this is another place where confusion could arise.

    I think there is a significant difference though: For indirect object syntax, Perl has to use heuristics that are also based on things not near the piece of code being parsed (spooky action at a distance), so that when encountering e.g. new File $path, $data, both perl and the human reading the code have to "guess" as to what was meant. For hash keys on the other hand, the rules for what is autoquoted are clear, so the only potential for confusion is on the side of the programmer not knowing the autoquoting rules. $hash{key} is always the same as $hash{"key"}, no matter if the bareword key is also a filehandle, sub, package name, etc. - but OTOH, for example $hash{a b} is not the same as $hash{"a b"}, which is sometimes surprising to coders. Further reading:

    • my node here with tons of examples

    • Scalar value constructors

      In fact, 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'}++.
    • Comma Operator

      The => operator (sometimes pronounced "fat comma") is a synonym for the comma except that it causes a word on its left to be interpreted as a string if it begins with a letter or underscore and is composed only of letters, digits and underscores. This includes operands that might otherwise be interpreted as operators, constants, single number v-strings or function calls. If in doubt about this behavior, the left operand can be quoted explicitly.
    • Identifier parsing

    Minor edits for clarity.

      Perl has to use heuristics that are also based on things not near the piece of code being parsed (spooky action at a distance)...

      Thankyou for the apt analogy haukex. As a physics nut, you just made my day. :)

        Glad to hear it :-) Though I'm not the first to use that phrase in reference to Perl (nor am I claiming that link is the first usage, it's just the earliest I found with a quick search).

Re: Quoting hash keys
by kcott (Archbishop) on Nov 09, 2021 at 05:48 UTC

    G'day Bod,

    I was certain that at some point I saw the rules for this but I'm buggered if I can now find that doco. The rules for the LHS of => (see perlop: Comma Operator) are almost (if not exactly) the same: use that as a guide.

    LanX showed key() and (key); you can also use a unary plus, i.e. +key (which is what I tend to use more often than not). Consider these:

    $ perl -E ' use constant X => "a"; sub Y {"b"} my %h = qw{a 1 b 2 X 24 Y 25}; say for $h{X}, $h{"X"}, $h{+X}, $h{X()}, $h{(X)}; say for $h{Y}, $h{"Y"}, $h{+Y}, $h{Y()}, $h{(Y)}; ' 24 24 1 1 1 25 25 2 2 2

    If the key looks even vaguely ambiguous, I will quote it; otherwise, I rarely do.

    — Ken

Re: Quoting hash keys
by LanX (Saint) on Nov 09, 2021 at 00:52 UTC
    > Is there a difference between $hash{ key } and $hash{'key'}?

    no, but there is an opposite issue if key is a sub or a constant .

    you'll need $hash{ key() } or $hash{ (key) } then.

    not really a problem for me, YMMV.

    > I always quote it unless the key is non-constant.

    I don't understand.

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

      > I always quote it unless the key is non-constant. I don't understand.

      Sorry for the ambiguity.

      By non-constant I mean anything that is either a variable or intopolates a variable. Such as $var or qq[st_$id]

Re: Quoting hash keys
by ikegami (Patriarch) on Nov 10, 2021 at 17:41 UTC

    Is there a difference between $hash{ key } and $hash{'key'}?

    Just the visual ones. (I consider the latter more cluttered.)

    As the chart indicates, the "autoquoting" has extreme precedence, so you don't even have to worry about using a key with the same name as an operator.

    $ perl -M5.010 -e'$h{ die } = 1; say "ok";' ok

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11138587]
Approved by LanX
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (4)
As of 2024-04-19 13:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found