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

OK. I'm stumped on this one.

I need to create a series of variables (with names like $db) which contain the values associated with their respective keys from the configuration module.

Here is what I'm trying to use; with the right side of that assignment replicating the syntax I'm already using repeatedly and successfully to extract data from my configuration hash. My question then is this: How do I set the variable name to match it without writing a dozen lines of repititious code here.

Update

shmem: or anyone really, if you have a real url for that article, that would be of interest to me. Thanks to all, a no strict refs; statement inside the foreach loop moved me past that one. I'm slowly refactoring a crudgy old but working cgi scripts' subroutines into module methods. Was trying to go the route of change only one thing at a time, ergo wishing to bridge how I coded two years ago before I discovered the wisdom of the monestary with how I code now, with a better understanding of objects and hashes. So far, that 300 line subroutine has served as fodder for one public and two substantive private methods, plus a couple of real short ones.

foreach my $config ('db','prefix','template','use_db','list_mail','sub +_method','email_metho d','debug_level','subscription_thanks_copy','campaign_type'){ ${$config} = $supporters_conf::config->{$config}; }
I'm seeing errors reading:

Can't use string ("db") as a SCALAR ref while "strict refs" in use at +/e6/run/cgi/supporters/MailingList.pm line 124.
All ideas are appreciated.

-- Hugh

if( $lal && $lol ) { $life++; }

Replies are listed 'Best First'.
Re: dynamically creating variables
by nedals (Deacon) on Nov 02, 2006 at 07:54 UTC
    You cannot create variables on the fly while using strict. The solution is to use a hash instead.
    my %config_hash; my @config_vars = qw/db prefix template use_db list_mail sub_method em +ail_method debug_level subscription_thanks_copy campaign_type/; for (@config_vars) { $config_hash{$_} = $supporters_conf::config->{$_}; }
Re: dynamically creating variables
by bobf (Monsignor) on Nov 02, 2006 at 07:56 UTC

    Why do you need to create new variables? They already appear to be in a hash, which is the data structure that is usually suggested when someone says they want variables with particular names. Perhaps I'm missing something.

    Incidently, you're getting that error because you are trying to dereference a string (${$config} becomes ${ 'db' }, not the variable $db).

    You can do what you're asking but it requires using soft (aka symbolic) references (perlref), which is usually a Bad Thing. See also Why it's stupid to use a variable as a variable name.

    Update: added link to perlref

      Incidently, you're getting that error because you are trying to dereference a string (${$config} becomes ${ 'db' }, not the variable $db).

      Well, if $config contains the string db, ${$config} is a variable $db. It's not a lexical variable, but a package variable. Still, addressing it with $db works just fine (provided there isn't a lexical $db in the current scope).

      my $config = 'db'; ${$config} = 'foo'; print $db, "\n"; __END__ foo
Re: dynamically creating variables
by shmem (Chancellor) on Nov 02, 2006 at 08:56 UTC
    What you're trying to do can be done, as other posters pointed out, but it's generally a bad idea. See Dominus mail Why it's stupid to `use a variable as a variable name' in comp.lang.perl.misc.

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: dynamically creating variables
by Zaxo (Archbishop) on Nov 02, 2006 at 08:29 UTC

    The comments above are correct.

    You're asking to duplicate information using a worse method of access. Go directly to the configuration hash instead.

    After Compline,
    Zaxo

Re: dynamically creating variables
by jbert (Priest) on Nov 02, 2006 at 14:30 UTC
    All the "no strict refs" and "don't do that" comments are pretty much on the money. If you *do* have a good reason for doing it, you can also use string eval:
    #!/usr/bin/perl use strict; use warnings; our $f; eval '$f = 10;'; print "f is $f\n";
    Where you make up the string to contain the code you need, for each assignment.

    If you can change your save format, this is something Data::Dumper can do for you automatically. "You can specify names for individual values to be dumped if you use the "Dump()" method".

Re: dynamically creating variables
by fenLisesi (Priest) on Nov 02, 2006 at 07:55 UTC
    A no strict 'refs', placed in as little a scope as possible, may help: