Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Re: Nervously....How do I access the Name of a Perl variable?

by wog (Curate)
on Jun 11, 2002 at 01:35 UTC ( [id://173363] : note . print w/replies, xml ) Need Help??


in reply to Nervously....How do I access the Name of a Perl variable?

Getting the line number and filename is relatively easy:

sub trace { my($package, $filename, $line) = caller; # ... }

You can also get the subroutine its in. See the docs for caller.

Getting the names of the relevant variables is much harder, because perl does not such a convinent mechanism for compile-time expanded macros as C. However there are things called source filters, and the Filter::Simple module provides a nice interface to them. So, we can use that to make a module that adds a TRACE() macro:

package TraceMacro; use Filter::Simple; FILTER_ONLY code => sub { s/TRACE\(\s*([^)]+)\s*\)/__PACKAGE__."::_trace(q($1),$1)"/eg; }; # replace each TRACE(...) with <this package>::_trace(q(...),...) sub _trace { my($names,@values) = @_; my @names = split /\s*,\s*/, $names; # extract varnames my($package,$file,$line) = caller; foreach my $i(0..$#names) { print STDERR "$file ($line): $names[$i]:'$values[$i]'"; } }

(The module just needs to be saved appropriately to a file called by the name of Package.pm where Package is whatever's specified by the package declaration. (You could change that.))

This has the side-effect of allowing arbitrary expressions instead of just variable names.

update: Usage would be like:

use TraceMacro; # ... TRACE( $foo, $bar );
If you want to change TRACE to trace (I prefer that compile-time-special things be uppercased), then it shouldn't be hard to fiquire that out.

Replies are listed 'Best First'.
Re: Re: Nervously....How do I access the Name of a Perl variable?
by Anonymous Monk on Jun 11, 2002 at 03:42 UTC

    Outstanding! Everything I wanted and an object lesson in creating my first package, which I didnt really think I was up for yet but this looks simple enough that even I can do it! Thankyou. Anyone with a spare vote handy, give it to this man.

    Of course, it will start out as cut&paste for now, but you gave me enough hints for possibilities that I can add (like sub name) to encourage me to investigate the references.

    To other responders:

    I am aware of the debugger and use it if I get something that needs it, but while im just cranking code out, sticking a TRACE in various places and running the prog is a nice quick way of checking things are doing what I expect or not.

Re: Re: Nervously....How do I access the Name of a Perl variable?
by Anonymous Monk on Jun 11, 2002 at 03:59 UTC

    Sorry for the second post here but reading the code I thought of one more feature that may be possible.and will try to work out for myself, but I am unsure of the side effects.

    If a SINGLE value is passed, how hard would it be to have it eval the passed expression and then return that from _trace()?

    That way, the TRACE macro could be used in-situ in the code, and by a suitable test of some flag (possibly the systems debug settings) either Trace or not trace and the program would still fuction (possibly inefficiently).

    Does this thought have any merit?