in reply to Problem with constant pragma and some hash definitions

Constants declared with use constant are problematic when used as hash keys. Constants are actually implemented as functions. In hash lookups and on the left hand side of a fat comma ('=>'), barewords are interpretted as strings rather than function calls. You can get the effect you want by prefixing them with a '&' and forcing them to be called as functions like this:

my %generator_lookup = ( &E_MESYSTEM => 'G_SYSTEM_SYSTEM_ID', &E_MEENTITY => 'G_ENTITY_ENTITY_ID', );

-sauoq
"My two cents aren't worth a dime.";

Replies are listed 'Best First'.
Re: Re: Problem with constant pragma and some hash definitions
by flounder99 (Friar) on Jul 18, 2003 at 19:10 UTC
    Another way around this is
    my %generator_lookup = ( E_MESYSTEM , 'G_SYSTEM_SYSTEM_ID', E_MEENTITY , 'G_ENTITY_ENTITY_ID', );
    The comma operator does not quote the lefthand side like => does. Just as a side note, I did notice that vim correctly color coded the source when I cut and pasted your code. The constants where correctly colored as quoted strings when I pasted them in, when I changed the => to , the E_MESYSTEM and E_MEENTITY changed color indicating they where not quoted strings. That is very useful.

    --

    flounder

      Avoiding the fat comma doesn't help in the case of hash lookups though. And, since you have to write it as $generator_lookup{&E_MESYSTEM} when looking it up, you might as well put the ampersand in when initializing it too, even if only for the sake of consistency.

      -sauoq
      "My two cents aren't worth a dime.";
      
Re: Re: Problem with constant pragma and some hash definitions
by dbush (Deacon) on Jul 18, 2003 at 18:42 UTC

    Many thanks sauoq for your rapid answer. Just one follow up question if I may; is there any downside in doing this? In the real bit of code there will be 30-40 values at a maximum.

    Regards,
    Dom.

      Actually there is. As soon as you add that ampersand the constants cease to be constants. And instead of inlining the value during compile-time, Perl actually calls the functions each time. Therefore I'd rather add an empty pair of braces:

      %hash = ( FOO() => 'FOO description, ...)
      Try to run these three and see the difference:
      perl -MO=Deparse -e "use constant FOO => 5; print FOO,qq{\n};" perl -MO=Deparse -e "use constant FOO => 5; print &FOO,qq{\n};" perl -MO=Deparse -e "use constant FOO => 5; print FOO(),qq{\n};"

      Jenda
      Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.
         -- Rick Osborne

      Edit by castaway: Closed small tag in signature

        there is another option you left out, which makes use of the unary "+" operator.

        perl -MO=Deparse -e "use constant FOO => 5; print +FOO,qq{\n};"

        which parses correctly. this syntax is idiomatic, and is the method i would prefer.

        ~Particle *accelerates*

      Just one follow up question if I may; is there any downside in doing this?

      A downside to using the ampersand notation? Not except for needing to keep track of where you need one and where you don't. (I actually think of that as a downside to using constant.)

      Update: "Actually, there is." Jenda is right.

      -sauoq
      "My two cents aren't worth a dime.";
      
Re: Re: Problem with constant pragma and some hash definitions
by Anonymous Monk on Jul 21, 2003 at 22:59 UTC
    instead of prefixing with ampersand, you can force them as a sub call: "E_MESYSTEM()" etc.
      instead of prefixing with ampersand, you can force them as a sub call

      Actually, prefixing them with an ampersand does force a sub call and, as Jenda pointed out elsewhere in this thread, that isn't always desirable. Using parens, as you suggest, leaves the constants as candidates for inlining. When they are inlined, they aren't sub calls at all, but substituted at compile time with their value. That's a good thing precisely because it saves you that call overhead.

      -sauoq
      "My two cents aren't worth a dime.";