I tried to use constant
values in perl and stumbled upon the following weird behaviour:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
use constant {
a => "b"
};
my $c = { a => a };
my %d;
$d{a} = a;
print Dumper($c);
print Dumper(\%d);
will output
$VAR1 = {
'a' => 'b'
};
$VAR1 = {
'a' => 'b'
};
The constant a
was replaced on the right hand side of the expressions $d{a} = a
and a => a
, but not on the left side.
I know that constants are implemented using inlinable subs (documented here) and that sub names evaluate to their names if they aren't predeclared (documented here), but I can see no reason why in my example a
evaluates once to the value and once to the name in the same line of code, especially in the assignment to the hash - The a => a
might be a consequence of =>
interpreting the left site as a string if it begins with a letter.
Sidenote: Adding parantheses to make the sub-call explicit yields the expected result:
# ...
my $c = { a() => a }; # or my $c = { a, a };
my %d;
$d{a()} = a;
# ....
Output:
$VAR1 = {
'b' => 'b'
};
$VAR1 = {
'b' => 'b'
};
(all examples tested with perl 5.18)
The end of the constant page, at CAVEATS, has the answer
You can get into trouble if you use constants in a context which automatically quotes barewords (as is true for any subroutine call). For example, you can't say
$hash{CONSTANT}
becauseCONSTANT
will be interpreted as a string.
It then proceeds with the solution you found
Use
$hash{CONSTANT()}
or$hash{+CONSTANT}
to prevent the bareword quoting mechanism from kicking in.
Then it spells this out for hashes as well
Similarly, since the
=>
operator quotes a bareword immediately to its left, you have to sayCONSTANT() => 'value'
(or simply use a comma in place of the big arrow) instead ofCONSTANT => 'value'
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With