Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Special literals taken literally

by xdg (Monsignor)
on Apr 14, 2006 at 03:43 UTC ( #543280=perlmeditation: print w/ replies, xml ) Need Help??

Sometimes, mistakes stare you in the face and you still miss them. This brief meditation is on the topic of special literals, one of which recently caused a frustrating bug for me. Realizing what had happened was a bracing reminder about when to use the cruciform operator.

For beginning to intermediate monks, ponder the following code snippet:

# In the file 'literal.pl' package Illumination; use strict; use warnings; use Data::Dumper; my %hash; $hash{__PACKAGE__}{__FILE__}{__LINE__} = "Mu Mu"; print Dumper \%hash;

What will it produce? Check your answer.

-xdg

Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

Comment on Special literals taken literally
Download Code
Re: Special literals taken literally
by bobf (Monsignor) on Apr 14, 2006 at 03:58 UTC

    Interesting. Apparently, I would have made the same mistake you did. :-)

    From perldata (emphasis mine):
    The special literals __FILE__, __LINE__, and __PACKAGE__ represent the current filename, line number, and package name at that point in your program. They may be used only as separate tokens; they will not be interpolated into strings. If there is no current package (due to an empty package; directive), __PACKAGE__ is the undefined value.
    The original code gives:
    $VAR1 = { '__PACKAGE__' => { '__FILE__' => { '__LINE__' => 'Mu Mu' } } };
    But the "cruciform operator" can be used to interpolate tokens:
    $hash{+__PACKAGE__}{__FILE__}{__LINE__} = "Mu Mu";
    $VAR1 = { 'Illumination' => { '__FILE__' => { '__LINE__' => 'Mu Mu' } } };

    Double-cruciform (++) for the reminder.

Re: Special literals taken literally
by diotalevi (Canon) on Apr 14, 2006 at 05:38 UTC

    Well, err, yeah. Shouldn't this have been obvious to you? Fat comma has the same effect. That hash subscripts are treated as strings is nothing new. You've known you can type $foo{BAR} without having to quote "BAR". This is just the same rule. No special magic at all. In fact, that's thing. There's less magic here.

    ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

      Well, err, yeah. Shouldn't this have been obvious to you?

      Yes, it should have. I kicked myself when I realized what I did. This meditation is a reminder, not a discovery.

      -xdg

      Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

Re: Special literals taken literally
by larryl (Scribe) on Apr 14, 2006 at 16:42 UTC

    Good point - I was recently similarly burned by something like this:

    use constant FOO => 'my hash key'; my %hash = ('my hash key' => 42); print "Wahoo!\n" if exists $hash{FOO};


    Larry

Re: Special literals taken literally
by TimToady (Parson) on Apr 14, 2006 at 22:51 UTC
    Interestingly, this is fixed two different ways in Perl 6. Instead of special tokens, we have compiler variables like $?PACKAGE and $?FILE. And even if they were still bare identifiers, it would still work, because curlies no longer autoquote. We now use a different notation (angle brackets) for constant string subscripts.

    Sorry, I usually try to resist saying "fixed in six", because you'd get tired of it if we said it as often as it's true...

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlmeditation [id://543280]
Approved by kvale
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (6)
As of 2014-09-22 06:26 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (182 votes), past polls