Re: Problem with constant pragma and some hash definitions
by sauoq (Abbot) on Jul 18, 2003 at 18:36 UTC
|
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.";
| [reply] [d/l] |
|
|
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 | [reply] [d/l] [select] |
|
|
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.";
| [reply] |
|
|
| [reply] |
|
|
%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 | [reply] [d/l] [select] |
|
|
|
|
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.";
| [reply] |
|
|
instead of prefixing with ampersand, you can force them as a sub call: "E_MESYSTEM()" etc.
| [reply] |
|
|
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.";
| [reply] |
Re: Problem with constant pragma and some hash definitions
by Enlil (Parson) on Jul 18, 2003 at 18:41 UTC
|
| [reply] |
Re: Problem with constant pragma and some hash definitions
by perrin (Chancellor) on Jul 18, 2003 at 18:44 UTC
|
You can't use constants in a quoted context (like the left side of a => operator) without calling them as subroutines. This is why I advise people to avoid the use of the constant pragma. Just use globals instead. | [reply] |
|
|
Don't use globals. If you have a problem with constants, I would use a singleton or a globals hash. Single globals become a serious problem.
------ We are the carpenters and bricklayers of the Information Age. Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement. Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.
| [reply] |
|
|
Globals aren't that bad. They are package scoped afterall, and very efficient too. If you use a convention, like consistently using uppercase for constants, you shouldn't have many problems. If you want to keep the constants private, you can use file scoped lexicals instead of globals and protect yourself even further.
A global hash isn't a terrible alternative, but the syntax is messy and you don't benefit from strict checking.
But a singleton? Ugh...
How about a tied scalar? (just kidding)
-sauoq
"My two cents aren't worth a dime.";
| [reply] |
|
|
I don't see a problem with using globals for constant values. They have the same scope as the subroutines created by the constant pragma.
| [reply] |