Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

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

by xorl (Deacon)
on Jun 19, 2012 at 11:10 UTC ( [id://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

Replies are listed 'Best First'.
Re: using a string as a SCALAR ref while "strict refs" in use
by Anonymous Monk on Jun 19, 2012 at 11:27 UTC
      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.
        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.

        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 "; }

      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

Re: using a string as a SCALAR ref while "strict refs" in use
by tobyink (Canon) 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" }
Re: using a string as a SCALAR ref while "strict refs" in use
by daxim (Curate) 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

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
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?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (5)
As of 2024-03-28 16:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found