-
When Magics Collide
2007-01-12 21:00 in /tech/perl/HallOfShame
I haven’t posted a Hall of Shame entry in a while, and this one adds a new twist. Today, it’s perl itself that gets the blame. (I know, some will say that’s always the case.) This is about when two magics collide.
There are a couple magic tokens that you can use in perl scripts to represent the current context, like
__PACKAGE__and__LINE__. These tokens behave differently from variables, and one example of this is that they don’t interpolate inside strings.For reasons of backwards compatibility, when perl encounters a bareword that it doesn’t recognize, it ‘auto-quotes’ it (treats it as a string). This is generally considered A Bad Thing and the
strictpragma forbids it. Except for when it doesn’t, and that exception is hash keys. So, even withstrict, a bareword hash key is magically auto-quoted.Now, consider this code:
package foo; use strict; my %h; $h{__PACKAGE__} = "bar"; while (my ($k, $v) = each %h) { print "$k => $v" };I think it’s clear that anyone writing this code expects the output to be
foo => bar
Unfortunately, it’s actually
__PACKAGE__ => bar
What’s happened is that perl has auto-quoted the string before doing the token substitution. In order to get the desired behavior, it’s necessary to resort to atrocities like
$h{__PACKAGE__ . ""} = "bar";or
$h{+__PACKAGE__} = "bar";to get the job done
Comments
Rain wrote:
Bill wrote:
Leave a comment
Please use plain text only. No HTML tags are allowed.
Comments are closed for this story.
Trackbacks are closed for this story.