Does Perl have something similar to PHP's constant()?

constants, perl, php, variables

Solution

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}_]/;

Problem

I have done some digging through perldoc and the O'Reilly books but haven't found any way to do this. Am I relegated to using something like Readonly? UPDATE: I have nothing against Readonly. I just wanted to be able to do something like PHP's constant(). Example if Perl had constant(): ``` use constant { FIELD_EXAMPLE_O => 345, FIELD_EXAMPLE_L => 25 }; my $var = 'EXAMPLE'; my $c = 'FIELD_' . $var . '_L'; my $value = constant($c); # $value is 25 ``` If Readonly is the best way to do it, then I shall use it.

Original source