I'm posting this as an answer, to pick up from the comments - hashes vs. constants:
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
use Benchmark qw(:all);
use constant ABC => 'DEF';
use constant GHI => 'JKL';
my $ABC = 'DEF';
my $GHI = 'JKL';
my %test_hash = (
ABC => 'DEF',
GHI => 'JKL'
);
sub access_hash {
my $value = $test_hash{ABC};
my $value2 = $test_hash{DEF};
}
sub access_constant {
my $value = ABC;
my $value2 = GHI;
}
sub access_scalar {
my $value = $ABC;
my $value2 = $GHI;
}
my $count = 100_000_000;
cmpthese(
$count,
{ 'hash' => \&access_hash,
'constant' => \&access_constant,
'scalar' => \&access_scalar
}
);
Results:
Rate hash scalar constant
hash 9427736/s -- -7% -10%
scalar 10143017/s 8% -- -3%
constant 10492078/s 11% 3% --
So you're right - it's faster to use a constant. However, I'd suggest for an operation that runs at a rate of 10M/sec, 'saving' 5% (or even 10%) is simply not worth the hackery you'll need to do it.
But in the interests of actually answering the question - the root of this problem is that constant is defined at compile time, where variables ... aren't.
There's simply no hash existing when the constant is defined, so that isn't going to work. You're also quite limited in what you can actually do in a BEGIN block. My thought would be that you could probably run a 'compile' process to turn your config file into a .pm that you could then use.
package import_const;
use constant ABC => 'DEF';
use constant GHI => 'JKL';
Then use import_const; and access your constants as import_const::ABC. (Or use Exporter to bring them into the local namespace).
sub from_pkg {
my $value = import_const::ABC;
my $value2 = import_const::GHI;
}
Add that into the timing test:
Rate hash scalar imported constant constant
hash 9497578/s -- -6% -9% -9%
scalar 10063399/s 6% -- -4% -4%
imported constant 10473398/s 10% 4% -- -0%
constant 10492078/s 10% 4% 0% --
I think I'd still argue that the gains are marginal for the effort. Especially given use constant will surprise you with it's evil
There may be a module that can do what you need though:
CPAN modules for defining constants
use constantsis a pragma that gets called at compile time. Your variables are only there at run time. You cannot do that outside of aBEGINblock or in an eval. I'll write an answer in a bit with alternatives and explanation.