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

Hi,
I am willing to write a function that shows me what is stored inside each variable.
I wrote this but it is only working if the variables are set with "our".
# @_ is a list of variable name # if @_ contains "i" and "j" and $i == 42 $j eq "freeBSD", # the function should print : # i : 42 # j : freeBSD sub display_init { my @variables = @_; my $value; foreach (@variables) { eval("\$value=\$$_"); if (! defined($value) ) { $value = "undefined"; } print "$_ : $value\n"; } }

Replies are listed 'Best First'.
Re: issues with eval (get a variable's value)
by shmem (Chancellor) on Sep 12, 2007 at 13:20 UTC
    I wrote this but it is only working if the variables are set with "our".

    That works with my variables as well. However, those variables have to be in the same scope as your display_init function:

    my $i = 42; my $j = 'FreeBSD'; sub display_init { my @variables = @_; my $value; foreach (@variables) { eval("\$value=\$$_"); if (! defined($value) ) { $value = "undefined"; } print "$_ : $value\n"; } } display_init (qw( i j)); __END__ i : 42 j : FreeBSD

    --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: issues with eval (get a variable's value)
by ikegami (Patriarch) on Sep 12, 2007 at 13:21 UTC

    eval EXPR is capable of accessing lexicals.

    my $t = 'test'; print eval '$t'; # test

    As long as it can "see" them (i.e. As long as they are in scope)

    my $t1 = 'test1'; sub show { print eval "\$$_" for @_; } my $t2 = 'test2'; show(qw( t1 t2 )); # test1, but not test2

    It can't see a variable that no longer exists.

    { my $t = 'test'; sub show { print eval "\$$_" for @_; } } show(qw( t )); # Nothing

    It can't see a variable that is no longer in scope.

    { my $t = 'test'; sub foo { $t } sub show { print eval "\$$_" for @_; } } show(qw( t )); # Nothing

    ...unless the function with the eval EXPR captured it.

    { my $t = 'test'; sub show { $t; print eval "\$$_" for @_; } } show(qw( t )); # test

    Anyway, why aren't you passing the variable's value instead of its name?

Re: issues with eval (get a variable's value)
by j1n3l0 (Friar) on Sep 12, 2007 at 13:09 UTC
    If all you want to do is see (print) what's in a variable, why don't you try using Data::Dumper?

    Smoothie, smoothie, hundre prosent naturlig!
Re: issues with eval (get a variable's value)
by Corion (Patriarch) on Sep 12, 2007 at 13:22 UTC
      Thanks for all your answers, but it seems i am missing something.
      if i write
      my $t; sub show { print eval "\$$_" for @_; } sub init { $t = 'test'; show(qw( t )); } => nothing
      but if i write
      my $t; sub show { print $t; print eval "\$$_" for @_; } sub init { $t = 'test'; show(qw( t )); } => testtest
      So it seems eval can not find $t in the right scope but if i use $t in a usual way before calling eval, it can find it...
Re: issues with eval (get a variable's value)
by Anno (Deacon) on Sep 12, 2007 at 14:47 UTC
    Ah, I know where you're coming from. When I was new to Perl, I was trying to write exactly such a thing. Just like you I found lexical scoping to be a show-stopper. Years later I learned about a way around that and wrote a utility module Report.pm, exporting report() which works much like your proposed display_init(), except that it doesn't prepend a "$" to the given items.

    Fact of the matter is that I never use it. Inserting normal print/warn/die statements just comes more natural after all this time. The code is essentially the first version that ran, I never bothered to clean it up. Anyway, here it is:

    Anno
Re: issues with eval (get a variable's value)
by clinton (Priest) on Sep 12, 2007 at 13:03 UTC
    You are using symbolic references to refer to your variables, and variables declared with my do not have a symbol table entry. (see Symbolic_References).

    You could look at PadWalker to get access to lexical variables.

    Clint

    Update Thanks to ikegami for pointing out that you are not using symbolic references. I misread the code.

    Presumably then, your my variables are being declared within other subs, so they are not in the same scope as your display_init sub, and so are not visible.

      He's not using sym refs.