For Programmers: Free Programming Magazines  


Home > Archive > PERL Miscellaneous > June 2005 > symbol table question









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author symbol table question
Richard Trahan

2005-06-07, 4:01 pm

Consider the following code:

package mypackage;
$x = 7;
otherpackage::mysub($x);
....
package otherpackage;
sub mysub
{
# retrieve variable name here
}

In mysub, I would like to retrieve the name mypackage::x, as well as
the variable type (SCALAR). How do I do that? I know how to use
caller() to retrieve the caller's package, and I know how to iterate
through the caller's symbol table to retrieve symbolic names
and existence of types, but I don't know how to associate one
of them with the alias to $x in mysub, i.e., $_[0].

Any help, please. Thanks.
Brian McCauley

2005-06-07, 4:01 pm

Richard Trahan wrote:

> Consider the following code:
>
> package mypackage;
> $x = 7;
> otherpackage::mysub($x);
> ...
> package otherpackage;
> sub mysub
> {
> # retrieve variable name here
> }
>
> In mysub, I would like to retrieve the name mypackage::x, as well as
> the variable type (SCALAR). How do I do that? I know how to use
> caller() to retrieve the caller's package, and I know how to iterate
> through the caller's symbol table to retrieve symbolic names
> and existence of types, but I don't know how to associate one
> of them with the alias to $x in mysub, i.e., $_[0].



if ( \${"${caller}::$name"} == \$_[0] ) {
print "First argument to mysub is \$$name in package $caller\n";
}

> Any help, please.


More helpfull would be the advice "Don't do this". Package variables
are very rare in modern well written Perl code, most variables are
lexicially scoped so won't have a name in the symbol table. Some, of
course, could have more than one.

What are you trying to achive? This smells distictly X-Y.

If your subroutine really must take an argument that is a symbol table
entry (which I think is unlikely) then it is better to make it
explicitly do so. Actually I hate psudo-GLOBs so I'd pass a GLOBref.

$x = 7;
otherpackage::mysub(\*x);

Richard Trahan

2005-06-07, 4:01 pm

Brian McCauley wrote:
>
> What are you trying to achive? This smells distictly X-Y.
>

Thank you for your response. I hadn't thought of equating the references.

I am expanding the Track program in Damian Conway's book, chapter on
Ties. The procedure, for scalars, is to call a tracking class which ties
the tracked variable after setting up a hash object and some stuff in
the STORE and FETCH methods which record caller() info. The proc is
limited in that it does not print the variable names, and it's
cumbersome to look at source code to match caller() info to debug
output in order to determine what variable is being dumped.

Another limitation is that the Track class, as shown in Conway's
book, relies on sub aliasing of @_ to variables, provided they're
scalars. For example, the setup for tracking a scalar is:
Track->scalar($myvariable)
In Track::scalar(), $_[0] is the class name ("Track") and $_[1] is
aliased to $myvariable (I've never been quite sure what an alias
is under the hood, although I know it refers to the same memory
location). But if you try to do something like:
Track->hash(%myhash)
it doesn't work, since Perl flattens %myhash into a list, rather than
putting an alias into $_[1]. If you try something like
Track->hash(\%myhash), you get a reference in hash(), and I don't know
how to tie a variable if you only have a reference to it. (I think
dereferencing it produces a copy of the hash, not an alias.) Therefore,
the Track class cannot be expanded to include hashes using this procedure.

Instead, the program setting up the tracking must call
tie(%hash,"Track",@arglist); tie() seems to be a magic syntax that
doesn't flatten %hash. (This is not explained anywhere, AFAIK.)

I don't like symbol tables either, thank you, but I think they're
necessary when developing debuggers and IDEs.

BTW, if you're into Tk, could you have a look at my other post? That's a
more serious problem for me now, and I've had trouble finding Tk fellow
travelers.
Jim Gibson

2005-06-07, 8:57 pm

In article <s3lpe.3083$S62.3007@fe11.lga>, Richard Trahan
<rtrahan@optonline.net> wrote:

> Brian McCauley wrote:
> Thank you for your response. I hadn't thought of equating the references.
>
>

[problem with tie snipped]

>
> BTW, if you're into Tk, could you have a look at my other post? That's a
> more serious problem for me now, and I've had trouble finding Tk fellow
> travelers.


Have you looked at comp.lang.perl.tk ? I think they are hanging out
there.


----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= East/West-Coast Server Farms - Total Privacy via Encryption =---
Richard Trahan

2005-06-08, 8:58 am

Jim Gibson wrote:

> In article <s3lpe.3083$S62.3007@fe11.lga>, Richard Trahan
> Have you looked at comp.lang.perl.tk ? I think they are hanging out
> there.
>
>

Thank you. I would have found this before Google screwed up their Groups
by removing computer/programming/languages; now it doesn't show up
anywhere, but I found it in my browser subscriptions list.
Brian McCauley

2005-06-08, 3:59 pm

Richard Trahan wrote:

> Brian McCauley wrote:
>
> Thank you for your response. I hadn't thought of equating the references.
>
> I am expanding the Track program in Damian Conway's book, chapter on
> Ties. The procedure, for scalars, is to call a tracking class which ties
> the tracked variable after setting up a hash object and some stuff in
> the STORE and FETCH methods which record caller() info. The proc is
> limited in that it does not print the variable names,


Not all variables have names you know.

> and it's
> cumbersome to look at source code to match caller() info to debug
> output in order to determine what variable is being dumped.


Then extend the API to allow you to pass a descriptive string along with
the variable.

> Another limitation is that the Track class, as shown in Conway's
> book, relies on sub aliasing of @_ to variables, provided they're
> scalars. For example, the setup for tracking a scalar is:
> Track->scalar($myvariable)
> In Track::scalar(), $_[0] is the class name ("Track") and $_[1] is
> aliased to $myvariable (I've never been quite sure what an alias
> is under the hood, although I know it refers to the same memory
> location).


> But if you try to do something like:
> Track->hash(%myhash)
> it doesn't work, since Perl flattens %myhash into a list, rather than
> putting an alias into $_[1]. If you try something like
> Track->hash(\%myhash), you get a reference in hash(), and I don't know
> how to tie a variable if you only have a reference to it. (I think
> dereferencing it produces a copy of the hash, not an alias.)


I suggest you stop thinking that because it is wrong. Once you stop
thinking it your other problem goes away.

> Instead, the program setting up the tracking must call
> tie(%hash,"Track",@arglist); tie() seems to be a magic syntax that
> doesn't flatten %hash. (This is not explained anywhere, AFAIK.)


Perl's builtin functions are able have magic syntax that a user-defined
Perl function could not emulate. Some may even have syntax that not
even a user defined XS function could emulate. tie() one of these. You
can tell this because prototype('CORE::tie') is undef.

You can go some way towards the magic syntax using a prototype.
Prototypes are explained in perlsub. But because prototypes are
implemented as compile-time syntactic sugar and method calls are
resolved at runtime, a subroutine called as a method ignores its prototype.

> I don't like symbol tables either, thank you, but I think they're
> necessary when developing debuggers and IDEs.


There are two types of symbol table in Perl the first are internally
called stashes and externally know as packages or namespaces. The other
type of symbol table is known as a pad. If one says unqualified "symbol
table" one is assumed to mean stash.

In a typical (well written) Perl program the vast majority of variables
are lexically scoped and reside in pads. The next most prevelant
variables are anonymous ones that have no entry in either a stash or a
pad. And finally a tiny minority of variables exist in stashes.

I'm ignoring here special variables as documented in perlvar - these too
reside in stashes but you are unlikely to want to Track them and quite
often they can't be tied.

If you are writing debugging tools then you can manipulate pads using
PadWalker but in this case I would not recommend it - just pass the name
as another argument.

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2009 codecomments.com