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

I want to be able to get the value of a constant whose name is in a variable, like this:
use strict; use constant BLAH => 5; my $name = "BLAH"; my $value = (something)$name
I want this code to set $value = BLAH;
provided $name = "BLAH";
i don't know what the "something" is that needs to be done. I'd rather not have to loosen the strict requirement, but if i must, i must.
Any ideas on how to do this would be much appreciated.

Replies are listed 'Best First'.
Re: constant name in variable
by sauoq (Abbot) on Dec 02, 2002 at 22:04 UTC

    You should rethink your design a bit. The arguments against mixing data and metadata extend to constants as well as variables. After seeing what you are really attempting in your post here, it seems you might be better off with a hash than constants.

    -sauoq
    "My two cents aren't worth a dime.";
    
Re: constant name in variable
by dpuu (Chaplain) on Dec 02, 2002 at 20:40 UTC
    Your something could be eval. This works with "use strict".

    An alternative:

    my $value = do { no strict; &{$name} };
    --Dave
      sure enough, eval works.
      I also figured out that $var->() will work, which i believe is efectively the same thing.
      Thanks
Re: constant name in variable
by rir (Vicar) on Dec 02, 2002 at 20:45 UTC
    You don't want the quotes around BLAH.
    #!/usr/bin/perl -w use strict; use constant B => 5; my $name = B; my $value = $name; print "B gives: ", B, "\n\$name is: $name\n\$value is: $value\n"; __DATA_ B gives: 5 $name is: 5 $value is: 5
    Update From your followup I see I interpreted your question the wrong way.

    With your code there is no benefit to avoiding no strict; for a small scope. You merely hide the issues.

    Dispatch tables might suit your problem.

Re: constant name in variable
by shemp (Deacon) on Dec 02, 2002 at 21:13 UTC
    Thanks for all the suggestions. I believe i have a working version. This is for part of a name string analyzer. Here is exactly what im doing:
    use strict; use Carp; use constant { PREFIX => 1, SUFFIX => 2, TRUST => 3, DATE => 4, BUSINESS => 5, }; sub AUTOLOAD { my $self = shift @_; my $method = $AUTOLOAD; $method =~ s/.*:://; return if $method eq "DESTROY"; if ( $method !~ m/^Is(.+)$/ ) { confess "method = $method is not supported by AUTOLOAD!\n"; } my $token_type_value = eval( uc($1) ); if ( $@ ) { confess "invalid token type $1!\n"; } my ($token) = @_; return $self->_IsToken($token, $token_type_value); }
    then i can make method calls like:
    $analyzer->IsSuffix("PhD");
    And _IsToken() does various tests, mostly against a list of known identifiers to determine if the token is of the type being asked about.
      This seems like heavy sugar to avoid calling $analyzer->_IsToken() directly. Other than a preference for:
      $object->IsSuffix( "PhD");
      over
      $object->Is( SUFFIX, "PhD");
      I'm not seeing any reason to do this. Preference is a sufficient reason.

      Am I missing something?

        Preference is actually the main reason I've done it this way. It also allows an easy way to write an explicit IsSuffix(), to perform differently than what _IsToken(SUFFIX, ...) might do, if i need to create more in-depth analyzers than the trivial hash lookups that _IsToken() will be doing. That isn't a particularly great reason to do it this way though.
        I think i like practicing writing weird AUTOLOAD methods also, after having coded C++ for a number of years, which was much more annoying :)
        I am going to consider redesigning though.