Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

How can I turn a string into a variable name?

by mnooning (Beadle)
on Jan 09, 2010 at 19:05 UTC ( #816523=perlquestion: print w/ replies, xml ) Need Help??
mnooning has asked for the wisdom of the Perl Monks concerning the following question:

I want to check if more than one of the many GetOptions options were used, and I want to know which ones were used. More than one is not allowed. For a quick check, I tried with only three options. In the code below, which does NOT work, only the "two" should match.
use strict; my $one = 0; my $two = 1; my $three = 0; my @strings = qw (one two three); my @optionsToCheck = ($one, $two, $three); foreach my $string (@strings) { print "Option $string was used\n" if ( ${"$string"} ); }
I tried different variations, but could not seem to get it. I could use a key/value hash, but that seems overkill. Besides, if I added or took away options, I'd have to remember to change the hash, too. I suspect Perl has a simple answer, but I cannot see it.

Thanks

Comment on How can I turn a string into a variable name?
Download Code
Replies are listed 'Best First'.
Re: How can I turn a string into a variable name?
by ikegami (Pope) on Jan 09, 2010 at 19:13 UTC

    Don't.

    GetOptions( '--one' => \$one, '--two' => \$two, '--three' => \$three, ); die "Only one of options --one, --two and --three are allowed\n" if ( grep defined, $one, $two, $three ) > 1;
    or
    GetOptions( '--one' => \$opts{one}, '--two' => \$opts{two}, '--three' => \$opts{tree}, ); die "Only one of options @{[ sort keys %opts ]} are allowed\n" if ( grep defined, values(%opts) ) > 1;

    Update: Updated since I hadn't properly read the question initially.

Re: How can I turn a string into a variable name?
by chromatic (Archbishop) on Jan 09, 2010 at 19:15 UTC

    If you really cannot use a hash (and that's easily the best way to do this), install PadWalker and use my $lexicals = peek_my(0); to get a hash reference which you can use to manipulate all lexical variables bound to the current scope.

    (If manipulating Perl 5 internals from pure Perl still seems less overkill than using a hash, consider that PadWalker can read from and write to and even create lexicals in other scopes, ignoring encapsulation.)

      I can use a hash. It looks like that is what I will do. I was just hoping for a slicker way. Thanks
Re: How can I turn a string into a variable name?
by almut (Canon) on Jan 09, 2010 at 19:27 UTC

    In theory, you could write

    print "Option $string was used\n" if ( eval "\$$string" );

    But, as already said, don't.  eval in this context is definitely worse than using a hash, in almost every regard.

      Why use eval to do
      if do { no strict 'refs'; $$string };
        Why use eval

        ...because the OP used lexical variables.  Symbolic references ($$string) only work with package variables.

Re: How can I turn a string into a variable name?
by GrandFather (Sage) on Jan 09, 2010 at 21:58 UTC

    Where do the 'options' come from? If they are from the command line use Getopt::Long. If they are derived internally (perhaps through a GUI or command line interface) then you could:

    use strict; use warnings; my %options = map {$_ => 0} qw(one two three); $options{two} = 1; # Set in some unspecified place for my $option (grep {$options{$_}} keys %options) { print "Option '$option' was used\n"; }

    Prints:

    Option 'two' was used

    True laziness is hard work

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://816523]
Approved by NiJo
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (16)
As of 2015-07-07 19:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (93 votes), past polls