Search code examples
perlstring-interpolation

How do I interpolate the value in a string variable into a constant in Perl?


I am writing a function in Perl, where a string is passed as an argument, and I need to interpret the string into the referenced value. The string would look something like this: "Edible => 1;Fruit => STRAWBERRY;" Now, the variable part will be stored using hashes, however, the value is already defined using constants. My question is, once I store the value into a temporary variable, how do I convert it into the value of the constant? Here is some example code:

#!/usr/bin/perl

require Exporter;

our @ISA = 'Exporter';
our @EXPORT = qw(STRAWBERRY TANGERINE PEAR APPLE PERSIMMON FUNC_Interpreter);

use constant {
    STRAWBERRY => 1
   ,TANGERINE => 2
   ,PEAR => 3
   ,APPLE => 4
   ,PERSIMMON => 5
};

sub FUNC_Interpreter {
    my ($analyze_this) = @_;
    my @values;
    foreach my $str (split (/;/, $analyze_this)) {
        my ($key, $value) = split /=>/, $str;
        push (@values, @{[ $value ]});           # Problem line! I want to store the numeric value here. This doesn't work... :(
    }
}

FUNC_Interpreter ("HELLO=>TANGERINE;HELLO=>STRAWBERRY");

So basically, what I want to do is convert a string, which is actually the name of a constant stored in a variable, into a constant's value. Is this possible?


Solution

  • Constants can be treated as subs.

    {
       no strict qw( refs );
       push @values, $value->();
    }
    

    or

    push @values, ( \&$value )->();
    

    But that's a hackish risky approach. And the second version even hides that you are dangerously allowing the user to call any sub in any package. What I would do instead:

    my %lookup;
    BEGIN {
       %lookup = (
          STRAWBERRY => 1,
          TANGERINE  => 2,
          PEAR       => 3,
          APPLE      => 4,
          PERSIMMON  => 5,
       );
    }
    
    use constant \%lookup;
    
    push @values, $lookup{ $value };
    

    Using this approach, inputs can be validated trivially, and invalid inputs merely result in undef.