in reply to Accessing constants via symbol table possible?

Here's a little snippet to dump the constants declared by constant.pm in the current package:
sub dump_consts_in_current_package { no strict 'refs'; printf "%s => %s\n", $_, join ', ', $_->() foreach grep $_ =~ ('^' . __PACKAGE__ . '::'), keys %constant::d +eclared; }

A brief explanation of the code. Constants are special subroutines, check out perlsub, but can still be called as any other subroutine. I choose to treat it as a symbolic reference, and dereference it immediately with the arrow notation; see perlref. To get only the current package's constants I use grep() to filter out those that begin with the current package's name. The perhaps unusual pattern is nothing but an expression that's later interpreted as a pattern.

That's it. :)

(As a side-note: The grep() above won't be slow because of the "special" pattern. __PACKAGE__ is compile-time so a constant will be folded in, and two constants concatenated is optimized to be just one constant. This in combination with that identical patterns at the same place won't recompile makes this not impose any overhead. You could interpolate __PACKAGE__ and use the o modifier to make the pattern compile at program compile-time. (Update: If I interpolate it won't be precompiled anyway... so the only thing gained by using the o modifier is that reinterpolation won't occure.) But the o modifier doesn't work in activeperl, at least not my activeperl, so I never use it. (Update: Clarification per request: With the o modifier I mean the "compile only once" modifier you can put on pattern quote ops, like m/PATTERN/o.)

Hope I've helped,
ihb

Replies are listed 'Best First'.
Re^2: Accessing constants via symbol table possible?
by diotalevi (Canon) on Feb 07, 2003 at 16:50 UTC

    /o doesn't make the pattern compile at perl's compile time. It just means that when the expression is used and compiled it keeps the result instead of throwing away the compiled form. It doesn't imply that the regex itself is compiled at any particular time.


    Seeking Green geeks in Minnesota

      I'm sorry, I was obviously smoking. I didn't mean that /o makes the pattern compile at program compile-time. The idea was to make perl do precompilation (at compile-time) by making it a match operator instead of an expression. (Perl precompiles constant patterns.) The /o was supposed to make sure that the pattern wasn't recompiled. But how I managed to perform this logic I don't understand myself. Because if I interpolate, precompilation can't occure anyway. And the /o is close to totally unnecessary, since the pattern will be the same and the optimization I mentioned myself about identical patterns will kick in. So the only thing saved is interpolation time.