Search code examples
stringperlquotesbareword

What are the pitfalls in using bare words in Perl?


I understand that bare words can be used as strings in quoting operators (q//, qq//), hash keys, etc. I'm personally not too thrilled about this because I can't get over the mental expectation that a literal string should be quoted, as in C, C++. However, if I were to adopt mixed uses of quoted strings and bare words, I want to make sure that I don't accidentally shoot myself in the foot where bare words would not behave correctly at runtime.

Please exclude use cases where 'use strict' would catch them as errors at compile time. I always enable 'strict' mode, so I'm not concerned about these cases.

Below is a code illustration based on the answers and comments provided:

#!/usr/bin/perl

use strict;

use constant SIZE => "const_size";

sub size {
    return "getsize";
}

my $href = {
    size => 1,
    getsize => 2,
    const_size => "CONST_SIZE",
    SIZE => "LARGE",
};

print "constant SIZE:", SIZE, "\n";
print "1. \$href->{size}:", $href->{size}, "\n";
print "1a. \$href->{size()}:", $href->{size()}, "\n";
print "2. \$href->{getsize}:", $href->{getsize}, "\n";
print "3. \$href->{SIZE}:", $href->{SIZE}, "\n";
print "3a. \$href->{(SIZE)}:", $href->{(SIZE)}, "\n";

Output:

$ ./bare_word.pl
constant SIZE:const_size
1. $href->{size}:1
1a. $href->{size()}:2
2. $href->{getsize}:2
3. $href->{SIZE}:LARGE
3a. $href->{(SIZE)}:CONST_SIZE

It appears that with respect to hash keys, bare words behave as expected in all cases. To override the behavior, we'd need to explicitly disambiguate.


Solution

  • Please exclude use cases where 'use strict' would catch them as errors at compile time.

    use strict; entirely prevents the use of barewords. Allowing barewords allows typos to fail very silently and/or subtly.

    The documentation claims lowercase barewords could be misinterpreted as function calls in future versions of Perl, but that's not true. New functions would need to be enabled like say.


    That said, I think you actually mean to talk about auto-quoted hash keys. There is a potential for confusion in that one might write $hash{foo} expecting it to be equivalent to $hash{foo()}. But not only is foo (as opposed to foo()) a weird way to call a sub in the first place, noone would want to write $hash{foo()} in the first place. (An argument would surely be required.)

    The only thing preventing the chance of the code being misinterpreted from being infinitesimally small is the possibility of constants being used as hash keys. $hash{CONSTANT} would fail. One would need to use $hash{(CONSTANT)}, $hash{+CONSTANT}, or some other form of disambiguation.