getting {string} from \${string}

B

bongo

Hi folks. Perl newbie here. Having a heck of a
time with something which probably isn't that hard...

When debugging code in progress, I often find myself
typing:

print "\$var1=$var1, \$var2=$var2 \n";

not a big deal, but when you do it all the time, it
would be nice to save some typing by putting it in a
subroutine, such as:

dbg_pr($var1,$var2);

Easy enough if I just wanted the values, but I want to
print both the variable names and the values, and I'd
like to get both from one string. If I pass $var1 or \$var1
I can get the value but not the variable name, and if I
pass "var1" I get the name but not the value
(as ${"var1"} isn't defined in the subroutine name space.)

It doesn't seem like I can pass a string and construct a
reference from it. Can I somehow stringify \${var1} to
get "var1" instead of SCALAR(Hhex address)?

Any help appreciated. It seems as if this has to be simple,
but the best I can currently do is pass both the string and
the reference, which is almost as redundant as just retyping
the whole print statement every time.

thanks,
--bongo
 
G

Gunnar Hjalmarsson

When debugging code in progress, I often find myself
typing:

print "\$var1=$var1, \$var2=$var2 \n";

Me too. :)
not a big deal, but when you do it all the time, it
would be nice to save some typing by putting it in a
subroutine, such as:

dbg_pr($var1,$var2);

Easy enough if I just wanted the values, but I want to
print both the variable names and the values, and I'd
like to get both from one string. If I pass $var1 or \$var1
I can get the value but not the variable name, and if I
pass "var1" I get the name but not the value
(as ${"var1"} isn't defined in the subroutine name space.)

Maybe you should start using hashes more often instead of simple scalars...

my %hash = ( key1 => 'one', key2 => 'two' );
sub dbg_pr { my $ref = shift; print "$_=$ref->{$_}\n" for @_ }

dbg_pr( \%hash, qw/key1 key2/ );

Outputs:
key1=one
key2=two

Or hashes together with Data::Dumper:

use Data::Dumper;
my %hash = ( key1 => 'one', key2 => 'two' );

print Dumper \%hash;

Outputs:
$VAR1 = {
'key2' => 'two',
'key1' => 'one'
};
It doesn't seem like I can pass a string and construct a
reference from it.

Well..

our ($var1, $var2) = ('one', 'two');
sub dbg_pr {
my %vars = map { $_ => eval } @_;
print "$_=$vars{$_}\n" for @_
}

dbg_pr( qw/$var1 $var2/ );

( but don't take it too seriously ;-) )
 
J

jl_post

Hi folks. Perl newbie here. Having a heck of a
time with something which probably isn't that hard...

When debugging code in progress, I often find myself
typing:

print "\$var1=$var1, \$var2=$var2 \n";

not a big deal, but when you do it all the time, it
would be nice to save some typing by putting it in a
subroutine, such as:

dbg_pr($var1,$var2);


You can try using this subroutine:

sub printVar
{ my $v = shift; print "\$$v = ", eval "\$$v", "\n"; }


Then call it like this:

$var = 7;
printVar("var");
# or even like: printVar qw(var);

You'll see the output:

$var = 7

(You can easily modify the printVar() function to handle multiple
variables, if you wish.)

I hope this helps.

-- Jean-Luc
 
J

jl_post

(You can easily modify the printVar() function to
handle multiple variables, if you wish.)


Such as:

sub printVar { print "\$$_ = ", eval "\$$_", "\n" for @_ }


Then you can call it like:

my $wow = 5;
my $var = "hello";
printVar qw(wow var);

And you'll see the output:

$wow = 5
$var = hello

(Sorry about the separate post. This came to me right after I posted
my first response.)

-- Jean-Luc
 
G

Gunnar Hjalmarsson

You can try using this subroutine:

sub printVar
{ my $v = shift; print "\$$v = ", eval "\$$v", "\n"; }

Then call it like this:

$var = 7;
printVar("var");

That works only with file scoped variables, and hopefully most variables
are my() declared in the lowest possible scope.
 
A

Ala Qumsieh

would be nice to save some typing by putting it in a
subroutine, such as:

dbg_pr($var1,$var2);

Do you really need to print the leading '$'?

print "var1 = $var1.\n";

--Ala
 
A

Anno Siegel

Hi folks. Perl newbie here. Having a heck of a
time with something which probably isn't that hard...

When debugging code in progress, I often find myself
typing:

print "\$var1=$var1, \$var2=$var2 \n";

not a big deal, but when you do it all the time, it
would be nice to save some typing by putting it in a
subroutine, such as:

dbg_pr($var1,$var2);

Easy enough if I just wanted the values, but I want to
print both the variable names and the values, and I'd
like to get both from one string. If I pass $var1 or \$var1
I can get the value but not the variable name, and if I
pass "var1" I get the name but not the value
(as ${"var1"} isn't defined in the subroutine name space.)

It doesn't seem like I can pass a string and construct a
reference from it. Can I somehow stringify \${var1} to
get "var1" instead of SCALAR(Hhex address)?

No, not without Devel::peek.
Any help appreciated. It seems as if this has to be simple,
but the best I can currently do is pass both the string and
the reference, which is almost as redundant as just retyping
the whole print statement every time.

It's not trivial. You can use "eval" to get the value of an expression
given as a string (including simple variables). Then you can print
the literal expression and the value. Define two routines:

sub showval {
my ( $name, $value) = @_;
print defined $value ? "$name = $value\n" : "$name -undef-\n";
}

sub show {
join '; ', map "showval( '$_', $_)", @_;
}

(If you put them in a module, import both show() and showval().)

In a program, you may have:

my $x = 3;
my $y;
my %z = ( aaa => 123, bbb => 456 );

To see some of the values, say

eval show qw( $x $y $z{bbb} $z{gibsnich});

That prints

$x = 3
$y -undef-
$z{bbb} = 456
$z{gibsnich} -undef-

Close enough? Myself, I have it somewhere but never use it.

Anno
 
A

Anno Siegel

You can try using this subroutine:

sub printVar
{ my $v = shift; print "\$$v = ", eval "\$$v", "\n"; }


Then call it like this:

$var = 7;
printVar("var");
# or even like: printVar qw(var);

You'll see the output:

$var = 7

(You can easily modify the printVar() function to handle multiple
variables, if you wish.)

That only works for package variables, while these days most variables
are lexical. With those, "eval" must be called in their lexical scope
to access the value. Putting "eval" in a sub like that won't do.

Anno
 
J

Joe Smith

Such as:

sub printVar { print "\$$_ = ", eval "\$$_", "\n" for @_ }


Then you can call it like:

my $wow = 5;
my $var = "hello";
printVar qw(wow var);

And you'll see the output:

$wow = 5
$var = hello

No, you will not!

You'll see the output
$wow =
$var =
because variables declared with my() are not visible outside
there scope.

Did you even try running the code you posted?
-Joe
 
G

Gunnar Hjalmarsson

Joe said:
No, you will not!

You'll see the output
$wow =
$var =
because variables declared with my() are not visible outside
there scope.

You will see the former output with:

my $wow = 5;
my $var = "hello";
sub printVar { print "\$$_ = ", eval "\$$_", "\n" for @_ }
printVar qw(wow var);

i.e. if the sub is defined
1) within the same scope as, *and*
2) after
the variables.

But it's not an appropriate solution to the OP's problem.
 
J

jl_post

Joe said:
No, you will not!

You'll see the output
$wow =
$var =
because variables declared with my() are not visible outside
there scope.

Aargh! You're right!
Did you even try running the code you posted?

Yes, but I tried it inside the perl interactive intepreter ("perl
-de 1"), which I use a lot to test out various snippets of code. It
gets a little tricky handling code in there, because variables declared
with "my" go out of scope as soon as the command is completed (since
each line is technically its own block).

So I did run that code, but not with "my" (I added that in as an
afterthought so that my post would be consistent with "use strict").
Unfortunately, modifying my code wasn't as harmless as I thought.

Fortunately, other newsgroup posters (like you) pointed out my
error. Thanks for that.

-- Jean-Luc
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,070
Latest member
BiogenixGummies

Latest Threads

Top