|
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 Threads | Posted | | 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 |
|