What's wrong with Readonly
?
If it's too slow, you can supplement it with Readonly:XS
. But if you don't like Readonly
, there's always the older constant
.
use constant PI => 3.14159265;
Just remember
- They work like subs, so they don't interpolate without work.
If you want to create multiple constants in one statement, you need to pass a hash reference.
use constant { PI => 3.14159265
, E => 2.71828183
};
From Your Example:
Judging from your example, there's no reason why a readonly hash couldn't do the same thing.
Readonly::Hash my %field_example => { L => 25, O => 345 };
Then you could use it anywhere you'd want to cobble the constant:
print "The example is $field_example{$var}\n";
OR you could do it this way:
Readonly::Hash my %field
=> { example => { L => 25, O => 345 }
, name => { L => 'Lion', O => 'ocelot' }
};
And call it this way:
$field{$var}{L};
You can get a lot of mileage about not trying to make a language do what it has better support for doing in another way.
Cognate to PHP constant
However, if you want to do it that way, then my suggestion is that the following sub is a way of doing the same ( and avoids an eval
):
sub read_constant {
use Symbol qw<qualify_to_ref>;
my $name = join( '', @_ ); # no need to concatenate before passing
my $constant;
# use the first that works: calling package and then "" (main)
for my $pkg ( scalar( caller ), "" ) {
# get symbol reference
my $symb_ref = qualify_to_ref( $name, $pkg );
# get the code slot
$constant = *{$symb_ref}{CODE};
last if $constant;
}
return unless $constant;
# call the sub named
return $constant->();
}
You'd call it like this:
$value = read_constant( 'FIELD_', $var, 'L' );
One last thing, is that you could even put a test in front to make sure that it is only a all cap string:
Carp::croak "Invalid constant name '$name'" if $name =~ /[^\p{UpperCase}_]/;