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

I am trying to set a variable with in the key of a hash, and am seeing an error message

$pic = 1 print {$r3_filehandle_2} "set groups VPN-HE-TUNNEL-CUST$ip-ipsec1 in +terfaces $v->{R3R3_$pic\_IF} ";

while executing this i see this message. Bareword "_IF" not allowed while "strict subs" in use at oracle_setup.pm line 2376. Here R3R3_$pic\_IF is a key of hash v

Replies are listed 'Best First'.
Re: variable inside hash key
by toolic (Bishop) on Mar 29, 2016 at 14:21 UTC
    One way...
    use warnings; use strict; my $pic = 1; my $v = {R3R3_1_IF => 555}; my $key = "R3R3_${pic}_IF"; print "set groups interfaces $v->{$key}\n"; __END__ set groups interfaces 555

      Thank you, toolic. It worked

      I think increment of $pic is not happening with this method

      my $pic = 1; my $key_MS = "R3R3_${pic}_IF"; my $temp = 90; for (my $ip = 1; $ip<=100; $ip++) { if ($temp == $ip) { $pic++; } } print "New pic value is $key_MS\n"; output:New pic value is R3R3_1_IF

        $pic is being incremented. This however has absolutely no effect on $key_MS which was set and evaluated when $pic was still 1. If you want to have it re-evaluated every time it is referenced you would need a closure or an eval or similar. eg. (with the loop replaced for clarity)

        #!/usr/bin/env perl use strict; use warnings; my $pic = 1; my $key_MS = sub { "R3R3_${pic}_IF"; }; print "Old pic value is " . &$key_MS . "\n"; $pic = 2; print "New pic value is " . &$key_MS . "\n";
Re: variable inside hash key
by davido (Cardinal) on Mar 29, 2016 at 15:07 UTC

    This seems like a parse error, but it's hard to say that the current behavior isn't intentional. Here are a few similar snippets, and how they deparse with -MO=Deparse,x9:

    use strict; use warnings; my $pic = 1; my $v = {R3R3_1_IF => 100}; print "Hello world. $v->{R3R3_$pic\_IF}\n";

    The output with perl -MO=Deparse,x9 mytest.pl:

    Backslash found where operator expected at mytest.pl line 9, near "$pi +c\" (Missing operator before \?) Bareword "_IF" not allowed while "strict subs" in use at mytest.pl lin +e 9. mytest.pl had compilation errors. use warnings; use strict; my $pic = 1; my $v = {'R3R3_1_IF', 100}; print "Hello world. $$v{$pic->R3R3_(\'_IF')}\n";

    If you attempt to disambiguate using curly braces it still fails:

    use strict; use warnings; my $pic = 1; my $v = {R3R3_1_IF => 100}; print "Hello world. $v->{R3R3_${pic}_IF}\n";

    The output...

    Bareword found where operator expected at mytest.pl line 9, near "${pi +c}_IF" (Missing operator before _IF?) Bareword "_IF" not allowed while "strict subs" in use at mytest.pl lin +e 9. mytest.pl had compilation errors. use warnings; use strict; my $pic = 1; my $v = {'R3R3_1_IF', 100}; print "Hello world. $$v{$pic->R3R3_('_IF')}\n";

    In both cases the interesting deparse to me is $pic->R3R3_('_IF'), and the explanation appears to be that the parser seems to feel this is a fine time to see the construct as indirect object notation.


    Dave

Re: variable inside hash key
by AnomalousMonk (Archbishop) on Mar 29, 2016 at 19:42 UTC

    I think I prefer toolic's computation of  $key as a separate step (more readable/maintainable), but if you really need it all in one statement:

    c:\@Work\Perl>perl -wMstrict -le "my $v = { R3R3_foo_IF => 'xyzzy', R3R3_bar_IF => 'wibble', }; ;; my $pic = 'foo'; ;; print qq{whatever $v->{ qq{R3R3_${pic}_IF} } and so on}; " whatever xyzzy and so on
    (Note that I use  qq{...} instead of  "..." only to avoid distracting  \ escapes on the Windows command line.)

    Update: The trick is to realize that  $v->{ qq{R3R3_${pic}_IF} } is really  $v->{ EXPR } where EXPR is any expression whatsoever (but not a statement). So  $v->{ qq{R3R3_${pic}_IF} } evaluates to a scalar which is double-quote-ishly interpolated as usual.


    Give a man a fish:  <%-{-{-{-<

Re: variable inside hash key
by stevieb (Canon) on Mar 29, 2016 at 14:22 UTC

    Try double-quoting the key: $v->{\"R3R3_$pic\_IF\"}.

    update: I completely overlooked the outer quotes, so toolic's answer is the way to go to keep things clean.