in reply to indirect/symbolic access in perl

For the first chuck of code, I think it works better if you don't use comma in qw() and the DBG variables need to have a $ in front.

Here are the changes that I made to the first chunk code and the output.

bruce:1:~/tmp $ cat p.pl #!/usr/bin/env perl use strict; use warnings; use Readonly; my @EXPORTs = qw(DBG_ONE DBG_TWO DBG_FOUR) ; Readonly my $DBG_ONE => 1; Readonly my $DBG_TWO => 2; Readonly my $DBG_FOUR => 4; no strict 'refs'; foreach my $flag (@EXPORTs) { printf "flag = %s, value = 0x%04x\n", $flag, ${$flag}; } bruce:1:~/tmp $ ./p.pl Use of uninitialized value in printf at ./p.pl line 15. flag = DBG_ONE, value = 0x0000 Use of uninitialized value in printf at ./p.pl line 15. flag = DBG_TWO, value = 0x0000 Use of uninitialized value in printf at ./p.pl line 15. flag = DBG_FOUR, value = 0x0000

In pondering why the uninitialized value warnings were being displayed I remembered that you can't use symbolic references on my variables. So change the my to our and retry ...

#!/usr/bin/env perl use strict; use warnings; use Readonly; my @EXPORTs = qw(DBG_ONE DBG_TWO DBG_FOUR) ; Readonly our $DBG_ONE => 1; Readonly our $DBG_TWO => 2; Readonly our $DBG_FOUR => 4; no strict 'refs'; foreach my $flag (@EXPORTs) { printf "flag = %s, value = 0x%04x\n", $flag, ${$flag}; } bruce:1:~/tmp $ ./p.pl flag = DBG_ONE, value = 0x0001 flag = DBG_TWO, value = 0x0002 flag = DBG_FOUR, value = 0x0004

Much better.

Replies are listed 'Best First'.
Re^2: indirect/symbolic access in perl
by NetWallah (Canon) on Sep 20, 2007 at 14:16 UTC
    Your last piece of code does not work - You are attempting to de-reference $flag, which yields undef, and prints zero.

    This ugly code below does work:

    #use strict; use Readonly; my @EXPORTS=qw(DBG_ONE DBG_TWO DBG_FOUR); Readonly::Scalar my $DBG_ONE => 1; Readonly::Scalar my $DBG_TWO => 2; Readonly::Scalar my $DBG_FOUR => 4; foreach my $flag (@EXPORTS) { printf "flag = %s, value = 0x%04x\n", $flag, eval( "\$" . $flag ); }
    but I hate evals, and you would be much better served by using something like
    Readonly::Hash my %DBG_Val => (DBG_ONE => 1, DBG_TWO => 2, DBG_FOU +R =>4);
    Update:bruceb3's code works fine. Ignore the code I posted, which is essentially identical to bruceb3's but uses eval (and thus avoids conflict with "use strict 'refs'). Do follow the advice regarding using a Readonly HASH - much safer, and probably closer to what you need to do.

         "As you get older three things happen. The first is your memory goes, and I can't remember the other two... " - Sir Norman Wisdom

      re code working -- I did it from memory -- it was one of the iterations I went through while trying to find a workaround for the Readonly "bug" that was giving me a cryptic runtime message ("=28" isn't numeric")....
Re^2: indirect/symbolic access in perl
by perl-diddler (Chaplain) on Sep 20, 2007 at 17:09 UTC
    That's just weird...though I note someone seemed to get 'my' to work below by explicitly telling Readonly::(to use Scalar).

    I'm not clear on diffs between our and my -- I thought "our" was to allow a package to have 1 common var among all the objects of same type? (Vs. "my" giving separate copies).

    Especially odd as "our" only came in during 5.6...before that... "use vars?" maybe? Still, seems more than a bit arcane.

    Thanks,
    -l

    (at least I'm seeing I'm not entirely delusional...:-)).