Click here to get back home

Get variable from its name string or vice versa?

 HomeNewsGroups | Search | About
 comp.lang.perl.misc    Post an article   get this group's latest topics as an RSS feed add this group's latest topics to your My MSN content add this group's latest topics to your My Yahoo content
Subject Author Date
Get variable from its name string or vice versa? Jerry Krinock 05-09-2008
Posted by Peter J. Holzer on May 10, 2008, 2:31 pm
Please log in for more thread options
>> 98d7-64c1bc9ef4e3@k13g2000hse.googlegroups.com:
>> > I have written a function to log variables like this:
>> >
>> > " varName: varValue"
>
>> This is a FAQ:
>
>> perldoc -q "How can I use a variable as a variable name"
>
> I think the OP is looking for something a bit different, i.e.
> a way to get the name of variable from the variable itself.
> I.e. some hypothetical code like
>
> my $x = 10;
> logvar( $x );
>
> sub logvar {
> my $varref;
> print get_name_from_reference( $var ) . " " . $$var . "\n";
> }

I think what is needed in this case a macro, not a subroutine. You want
to turn

logvar( $x );

into

print '$x' . " " . $x . "\n";

and similarly

logvar( $foo-> );

into

print '$foo->' . " " . $foo-> . "\n";

Macros are not part of perl per se, but can be implemented via source
filters. It shouldn't be too hard to write a filter like that.

But it happens that Damian Conway already wrote one which might do what
the OP wants: Smart::Comments.

#!/usr/local/bin/perl5.10.0
use warnings;
use strict;
use Smart::Comments;


my $var = 5;
### At <where> ...
### $var
### At <where> ...: $var
__END__

prints:

### At "./foo", line 8 ...
### $var: 5
### At "./foo", line 10 ...: 5

        hp


Posted by Ben Bullock on May 10, 2008, 9:36 pm
Please log in for more thread options
On Sat, 10 May 2008 20:31:57 +0200, Peter J. Holzer wrote:

> But it happens that Damian Conway already wrote one which might do what
> the OP wants: Smart::Comments.

That's very handy. I'm glad to know about it.

Posted by jerrykrinock on May 13, 2008, 10:39 am
Please log in for more thread options

> I think what is needed in this case a macro, not a subroutine...
> Macros are not part of perl per se, but can be implemented via source
> filters. It shouldn't be too hard to write a filter like that.
>
Thank you, Peter. Indeed I do want a preprocessor macro, but I was
not aware that perl's preprocessor macros were called filters
(perlfilter).

> But it happens that Damian Conway already wrote one which might do what
> the OP wants: Smart::Comments.

Well, I want something which will log to the same file as Log::StdLog
does, so I wrote my own. It's got some rough edges and a kludge or
two, but it works and does not use any of the black magic. Here it
is. Thanks again for the help...

package LogVar ;

use Filter::Util::Call;

sub import {
my ($type) = @_;
my ($ref) = [];
filter_add(bless $ref);
}

sub filter {
my ($self) = @_;
my ($status);
if (($status = filter_read()) > 0) {
# Substitute for the one-argument version, LogVar(varName)
s /LogVar[\s]*\([\s]*($|\@|\%)([\w]+)[\s]*\)/doLogVar($2,
$1$2, info)/ ;

# Substitute for the two-argument version, LogVar(varName,
level),
# when the level is 'warn'.
# The 'warn' has to be treated specially because 'warn' is
# also a predefined function in perl and really weird things
# happen if I don't do this
s /LogVar[\s]*\([\s]*($|\@|\%)([\w]+),[\s]*warn[\s]*\)/
doLogVarWarn($2, $1$2)/ ;

# Substitute for the two-argument version, LogVar(varName,
level)
# for other levels
s /LogVar[\s]*\([\s]*($|\@|\%)([\w]+),[\s]*([\w]+)[\s]*\)/
doLogVar($2, $1$2, $3)/ ;

# Now, heres the tricky part. I need to define the functions
# doLogVar, doLogVarWarn (and makeDefined, which they call).
# For some reasons which I don't understand,
# (1) If I simply define sub doLogVar in this module, it is
# "not found" when it runs from the host program file.
# (2) If I change the calls to "LogVar::doLogVar", then it
runs,
# but nothing gets logged
# So, my workaround for these two problems is to add the
placeholder
# use logVarFunctions
# to the main program file and then replace it with the
function
# definitions using the following s///, except s''' is used
to
# avoid variable interpolations.
# This also has the advantage of using the same Log::StdLog
# initialization and thus the same level that is used in the
main
# program file.
s 'use[\s]*LogVarFunctions[\s]*;'
sub makeDefined {
my $var_ref = shift ;
if (!defined($$var_ref)) {
$$var_ref = "<undefined>" ;
}
}

sub doLogVar {
my $varName = shift ;
my $varValue = shift ;
my $level = shift ;
makeDefined($varValue) ;
my $msg = sprintf ("%24s: %s\n", $varName, $varValue) ;
print $level => $msg ;
}

sub doLogVarWarn {
my $varName = shift ;
my $varValue = shift ;
makeDefined($varValue) ;
my $msg = sprintf ("%24s: %s\n", $varName, $varValue) ;
print \'warn\' => $msg ;
}
'

}
$status;
}


1;

__END__

=head1 NAME

LogVar - Logs variable name and value using Log::StdLog

=head1 SYNOPSIS

# Your program file must be using Log::StdLog and
# have initialized it with a level.

# Both of these are necessary
use LogVar ;
use LogVarFunctions ;

my $myVar = 5 ;

# Log to Log::StdLog at default level 'info'
LogVar($myVar) ;

# Log to Log::StdLog at some other level
LogVar($myVar, trace) ;
LogVar($myVar, debug) ;
# ...
LogVar($myVar, none) ;


=head1 DESCRIPTION

This module provides a perl filter (see perlfilter), which is a
preprocessor.
It provides the macro LogVar() which extracts the variable name from
the
first argument and logs the variable name and value to the file
designated
in Log::StdLog, producing lines that are nicely aligned like this:

$myVar: 5
$name: Jerry
$weight: 150.3



Posted by advice please wireless 802.11 on May 9, 2008, 2:24 pm
Please log in for more thread options
> I have written a function to log variables like this:
>
> " varName: varValue"
>
> but it takes two arguments: the variable name as a string, and the
> variable symbol:
>
> logVar ("myVar", $myVar) ;
>
> sub logVar {
> my $varName = shift ;
> my $varValue = shift ;
> if (!defined($varValue)) {
> $varValue = "<undef>" ;
> }
> printf ("%16s: %s\n", $varName, $varValue) ;
>
> }
>
> Is there any way to get "myVar" from $myVar or vice versa, without
> foregoing 'strict' and 'warnings'?
>
> Note: My actual code uses Std::Log but the problem is the same.
>
> Thanks,
>
> Jerry Krinock

sounds like you need the (non-existent) Perl func uneval()


Posted by Ben Morrow on May 9, 2008, 3:37 pm
Please log in for more thread options

> I have written a function to log variables like this:
>
> " varName: varValue"
>
> but it takes two arguments: the variable name as a string, and the
> variable symbol:
>
> logVar ("myVar", $myVar) ;
>
> sub logVar {
>         my $varName = shift ;
>         my $varValue = shift ;
>         if (!defined($varValue)) {
>                 $varValue = "<undef>" ;
>         }
>         printf ("%16s: %s\n", $varName, $varValue) ;
> }
>
> Is there any way to get "myVar" from $myVar or vice versa, without
> foregoing 'strict' and 'warnings'?

You can do this with PadWalker. If you need more hints than that, you
probably shouldn't be trying... :)

Ben

--
I have two words that are going to make all your troubles go away.
"Miniature". "Golf".
[ben@morrow.me.uk]

Similar ThreadsPosted
Calling C++ from Perl and vice versa January 22, 2006, 12:08 pm
Can I call Perl module from TCL or vice versa? October 10, 2006, 11:51 pm
PERL ---> Move email from Inbox folder to another or vice versa in OUTLOOK August 4, 2006, 10:39 pm
Using a string as a variable name. October 5, 2004, 10:34 am
setting a variable from a string August 12, 2005, 2:48 am
replace string with variable May 29, 2006, 6:06 am
How to "convert" a string into a variable name? August 2, 2006, 11:58 am
Using a variable in a matching string November 21, 2006, 1:18 pm
How do i get the charactors inside the ( ) from a string variable March 25, 2006, 2:46 pm
Modifying and printing a string variable September 12, 2006, 2:31 am

Our other projects:

Art Dolls, Fairies and Mermaids - Sunnyfaces.net

Roy's Linux, Programming and Search Engines messages

1-Script XML SitemapXML Sitemap