SPUG: The string name of a variable (or any identifier)

Yitzchak Scott-Thoennes sthoenna at efn.org
Wed Jan 28 10:07:47 CST 2004


On Wed, 28 Jan 2004, Michael R. Wolf wrote:

>
> Anyone ever wanted to do something like this? I do it all the time in
> debugging, but I can't put it in a loop like this
>
> my ($x, $y, $z) = (1..3);
> @stuff_to_debug = ($x, $y, $z);
> foreach (@stuff_to_debug) {
>     printf "%s %d\n", $_.printable_name, $_;
> }
>
> To output this?
>
> $x 1
> $y 2
> $z 3
>
> Is there a way to find the current identifier name? That is, given $x
> or @y (or \$x or \@y), can you get back "$x" or "@y"?
>
> I'd even resort to a Dumper-type interface, requireing that I pass
> references, ala
>
>     @stuff_to_debug = (\$x, \$y, \$z);

In general, only a coderef stores a name (actually just a pointer back
to it's parent glob or to a special glob *__ANON__), and that's what
caller uses.  Other variables have no such context.

However, if you know you have lexicals, you can use the list of references
form, and for each one, check it against the values of the hash whose ref
is returned by PadWalker::peek_my(0) (trying levels higher than 0 if 0
fails).  Then the corresponding key will be the variable name.  I think
this fails if you have more than one variable of the same name in a sub,
and think it might also fail if in a recursive call to a sub.

If you have globals, you can use symbolic references.  (Or, if you really
want, do a search through all the symbol tables.)

Another way, would be to use eval:

for (qw/$x $y $z/) {
   eval "printf '%s %d\n', '$_', $_;"
}
(untested).




More information about the spug-list mailing list