Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

using a string as a SCALAR ref while "strict refs" in use

by xorl (Deacon)
on Jun 19, 2012 at 11:10 UTC ( #977027=perlquestion: print w/ replies, xml ) Need Help??
xorl has asked for the wisdom of the Perl Monks concerning the following question:

I have a list of variable names that I want to loop through and do stuff to the actual variable.

use strict; my @varlist = ("foo", "bar", "baz"); my ($foo, $bar, $baz) = ("1", "2", "3"); my $newfoo = "A"; foreach my $var (@varlist) { my $newvarname = "new" . $var; if (defined $$newvarname) { $$var = $$newvarname; } }

Of course I get the error "Can't use string ("newfoo") as a SCALAR ref while "strict refs" in use"

Searching I found can't use string as a SCALAR ref while strict refs which says to use a hard reference. However I have no clue how to do that in the foreach loop.

Further down in that node (and in other search results) suggest using a hash. I really don't see how to do that in my case.

What I'm trying to do is write a script that will update values in one of our app's config file. I just don't want to have to type a million lines of code to test each value to see if it should be updated or not. The above is what I came up with. If I can make that work, great. If there's a better way, let me know that too.

Thanks in advance

Comment on using a string as a SCALAR ref while "strict refs" in use
Download Code
Re: using a string as a SCALAR ref while "strict refs" in use
by daxim (Chaplain) on Jun 19, 2012 at 11:19 UTC
    What does the interface to your app's config file look like? Perhaps we can suggest something better.
      It's just a tie.
      use strict; use Tie::File; # skipping all sorts of fun to get to this: tie @array, 'Tie::File', "$mf_dir$filename", recsep => '}', autochomp +=> 0; $array[$user_section] =~ s/username =\> $username/username =\> $newuse +rname/; # or something like that
Re: using a string as a SCALAR ref while "strict refs" in use
by Anonymous Monk on Jun 19, 2012 at 11:27 UTC

      But that would only work with GLOBALS (our/vars ) not lexicals (my)

      If you want to get at lexicals (my vars) you should use PadWalker

      Well because I really don't want to turn strict off since as you point out using a variable as a variable name isn't the best idea. As I mentioned in my post, I'm willing to consider alternatives. I'm just not seeing how to implement the alternatives in my specific case.

        Well because I really don't want to turn strict off... strict is lexically scoped, you don't have to turn it off for the whole program

        no strict; if (defined $$newvarname) { $$var = $$newvarname; }
        but that will only work of the vars are our vars

        I'm just not seeing how to implement the alternatives in my specific case.

        You could improve upon your description ( post a more complete question), I don't see why a hash couldn't work

        my %hash = ( qw/ foo 1 bar 2 baz 3 / ); $array[$user_section] =~ s{ ^ username => (.*) $ }{ Dance( \%hash, $1 ); }xemg; sub Dance { my( $vars, $one ) = @_; my $name = $vars->{$one}; return "username => $name" if defined $name; die "no name for $one "; }
        I'm just not seeing how to implement the alternatives in my specific case
        Well, its difficult to know, since you don't show why you need a bunch of $newfoo variables, but the approach with a hash might be to have two hashes, one for the original vars, and one for the new vars; so something like
        use strict; my %vars = ("foo" => 1, "bar" => 2, "baz" =>3); my %newvars = ("newfoo" => "A"); foreach my $var (keys %vars) { my $newvarname = "new" . $var; if (defined $newvars{$newvarname}) { $vars{$var} = $newvars{$newvarname}; } }

        Dave.

Re: using a string as a SCALAR ref while "strict refs" in use
by tobyink (Abbot) on Jun 19, 2012 at 11:28 UTC

    You can't use a string as a reference while strict refs is in use. That's the whole point of strict refs. If you want to use a string as a reference, you should disable strict refs.

    no strict 'refs';

    Your question is a bit like asking, "I've put up a sign on my front gate which says 'No Dogs Allowed'. Now I can't let my dog into my garden. How do I let my dog into my garden?"

    If you want to use non-strict references, don't put up a sign (use strict) that says only strict references are allowed.

    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: using a string as a SCALAR ref while "strict refs" in use
by muba (Priest) on Jun 19, 2012 at 12:32 UTC
    Further down in that node (and in other search results) suggest using a hash. I really don't see how to do that in my case.
    use strict; use strict; use warnings; use Data::Dump qw(pp); my %oldvalue = ( foo => "1", bar => "2", baz => "3" ); my %newvalue = ( foo => "A" ); foreach my $key (keys %oldvalue) { if (exists $newvalue{$key}) { $oldvalue{$key} = $newvalue{$key}; } } pp \%oldvalue; # { bar => 2, baz => 3, foo => "A" }

    Or even simpler:

    use strict; use warnings; use Data::Dump qw(pp); my %oldvalue = ( foo => "1", bar => "2", baz => "3" ); my %newvalue = ( foo => "A" ); %oldvalue = (%oldvalue, %newvalue); pp \%oldvalue; # { bar => 2, baz => 3, foo => "A" }

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://977027]
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (10)
As of 2014-09-19 17:26 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (143 votes), past polls