dmitri has asked for the wisdom of the Perl Monks concerning the following question:

Dear Perl Monks,

I have several modules that use large tables to generate code and other tables, etc. Usually, these tables look like this:

use constant SOME_TABLE => { &SOMECONSTANT => [ &ANOTHER1 => sub { ... }, &CONST2 => sub { ... }, ], ....... };
These can go several levels deep. The problem I've run into is that I like the arrow notation, as it makes the tables easy and intuitive to read. However, since I use constants and left side of the arrow is placed in quotes, I have to call the constant explicitly, using ampersand.

The problem with this is that if such constant is undefined (due to a type-o, for instance), this error will not get caught until run-time. It would be neat to catch these bastards at compile-time, but then I have to lose the arrow and use a comma instead.

Question: is there a way to catch undefined subroutines at compile-time and keep using the arrow notation at the same time?

Replies are listed 'Best First'.
Re: Constants and arrow notation.
by davido (Cardinal) on Oct 28, 2004 at 18:45 UTC

    You can place the constant within parens, causing it to be checked at compiletime.

    use strict; use warnings; use Data::Dumper; use constant THIS => 100; print "Testing: \n"; my %hash = ( (THIS) => 200 ); print Dumper \%hash;

    Try that code with the "use constant" line commented out, and you'll see it generates a compiletime error. The error you'll get is something along the lines of:

    Bareword "THIS" not allowed while "strict subs" in use at mytest.pl line 12. Execution of mytest.pl aborted due to compilation errors.


    Dave

      Thank you so very much! That's exactly what I needed. Of course, this only works with use strict;.

      /dmitri dances the happy dance.

Re: Constants and arrow notation.
by samtregar (Abbot) on Oct 28, 2004 at 18:35 UTC
    I think you can do this by putting the code in a BEGIN block. A BEGIN block asks Perl for a bit of run-time during compile-time. Thus, if you've got something happening at run-time that you'd rather have happen during compilation, BEGIN will usually do the trick.

    -sam

Re: Constants and arrow notation.
by perrin (Chancellor) on Oct 28, 2004 at 18:41 UTC
    Maybe hashes with fixed keys would be a better approach here than constants.

      I guess perrin is talking about Hash::Util, with this, it lets you lock hash keys. One example as how to use that module:

      use Data::Dumper; use Hash::Util; use strict; use warnings; my $constants; $constants->{CONST_ABXCDEFG} = 1; $constants->{CONST_ABCXDEFG} = 2; $constants->{CONST_ABCDXEFG} = 3; $constants->{CONST_ABCDEXFG} = 4; $constants->{CONST_ABCDEFXG} = 5; Hash::Util::lock_keys(%{$constants}); print Dumper($constants); $constants->{CONST_ABCDEFGX} = 6;