symbol table question

Discussion in 'Perl Misc' started by Richard Trahan, Jun 7, 2005.

  1. 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.
    Richard Trahan, Jun 7, 2005
    #1
    1. Advertising

  2. 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);
    Brian McCauley, Jun 7, 2005
    #2
    1. Advertising

  3. 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.
    Richard Trahan, Jun 7, 2005
    #3
  4. Jim Gibson wrote:

    > In article <s3lpe.3083$>, 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.
    Richard Trahan, Jun 8, 2005
    #4
  5. Richard Trahan wrote:

    > 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,


    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.
    Brian McCauley, Jun 8, 2005
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Rio
    Replies:
    4
    Views:
    1,187
  2. Peter Shaggy Haywood

    Re: Accessing your own symbol table

    Peter Shaggy Haywood, Jul 18, 2003, in forum: C++
    Replies:
    2
    Views:
    312
    Peter Shaggy Haywood
    Jul 21, 2003
  3. baumann@pan
    Replies:
    1
    Views:
    742
    Richard Bos
    Apr 15, 2005
  4. Song Ma
    Replies:
    2
    Views:
    229
    Charles Oliver Nutter
    Jul 20, 2008
  5. Replies:
    6
    Views:
    1,778
Loading...

Share This Page