Reflection or discovery of object methods in perl?

Discussion in 'Perl Misc' started by Guest, Nov 9, 2004.

  1. Guest

    Guest Guest


    again i am trying to get some stuff working (this time CORBA...), and again
    i would need an inspection tool telling me what class an object is
    and what methods its possesses...

    i know UNIVERSAL::can but that one expects a method name, it doesn't spit
    out the whole list when not provided with a method name...

    so is there that type of mechanism in perl?

    Guest, Nov 9, 2004
    1. Advertisements

  2. Guest

    Anno Siegel Guest

    The class is easy: perldoc -f ref. Finding all methods can't be done.

    One could (conceivably) walk the symbol table of the class and extract
    all coderefs (plus, recursively, the classes on @ISA). But there is
    no way of telling if a sub is a public method (or a method at all),
    so you'd get a lot of garbage besides the actual methods, and no
    way to tell one from the other.

    Anno Siegel, Nov 9, 2004
    1. Advertisements

  3. Guest

    Guest Guest

    hmmm pity....
    ok! where do i find those symbol tables?
    Guest, Nov 9, 2004
  4. Guest

    Anno Siegel Guest

    In perldata, perlmod and perlsub, mainly.

    Here is an example that lists all subs in main (scratch the "grep"
    to see all symbols):

    sub foo {} # define a sub, or you won't see much
    print "$_\n" for grep defined( &{ $main::{ $_}}), keys %main::

    You'll have to use some nasty symrefs to make it use an arbitrary
    string instead of "main". That is one of the cases where symrefs
    are officially tolerated.

    Anno Siegel, Nov 9, 2004
  5. Guest

    Guest Guest

    interesting :D i was planning to use the 'can' method to achieve the same :D
    anyway thanks a lot!

    making myself an inspection class

    Guest, Nov 9, 2004
  6. Guest

    Uri Guttman Guest

    AS> Here is an example that lists all subs in main (scratch the "grep"
    AS> to see all symbols):

    AS> sub foo {} # define a sub, or you won't see much
    AS> print "$_\n" for grep defined( &{ $main::{ $_}}), keys %main::

    AS> You'll have to use some nasty symrefs to make it use an arbitrary
    AS> string instead of "main". That is one of the cases where symrefs
    AS> are officially tolerated.

    as my rule states, use symrefs only when you are munging (which covers
    searching :) the symbol table. :)

    Uri Guttman, Nov 9, 2004
  7. Guest

    Uri Guttman Guest

    B> interesting :D i was planning to use the 'can' method to achieve
    B> the same :D anyway thanks a lot!

    how would you use can() for introspection? you would have to search all
    possible strings and run can() on them.

    also with AUTOLOAD you can't fully tell what methods are there. autoload
    can handle any method, or decide what is available at run time or
    whatever. i find the concept of introspection to be weak and not needed
    much. but others seems to live on it. either you know the classes you
    want or you don't.

    Uri Guttman, Nov 9, 2004
  8. Guest

    Guest Guest

    yep that's what i do, spares one eval statement...
    that way i can separate also what are variables...

    BTW a chance to easily try to extrapolate what return type the subs
    might have (means without actually executing them...)?
    but not in my code :D
    well in most cases yes, when you are debugging a non working CORBA
    framework (at least non working for me...) with perl objects that have no
    (or nearly no) documentation, it can come in quite handy...


    Bruno.Boettcher at visualsphere dot com
    Unsolicited commercial email is NOT welcome at this email address
    Guest, Nov 9, 2004
  9. Guest

    Peter Scott Guest

    Peter Scott, Nov 9, 2004
  10. Guest

    Guest Guest


    another problem rose now....

    uhm might seem stupid, but the ISA array is available only inside the
    objects themselves, seems i can't acces them from the outside...

    any way to get a hold of the super classes of an object?
    Guest, Nov 9, 2004
  11. Guest

    Anno Siegel Guest

    Anno Siegel, Nov 9, 2004
  12. Guest

    Anno Siegel Guest

    Huh? Can you explain that in code, please? What does it mean to be
    "inside" or "outside" an object? @ISA is a package variable and behaves
    like one in every aspect.
    Actually, objects don't have super classes, classes do.

    Get the object's class (we've been there already), which is also a package.
    Then use (another) symref to access @ISA in that package.

    Anno Siegel, Nov 9, 2004
  13. Dear Anno, please forgive me if I'm dumb: of course I have much less
    experience than you have, in these matters, but wouldn't it be better
    to grep on


    instead, especially in a more general setting, since we cannot rely on
    return values of subs (and we may risk side effects running them)?

    Also, were I doing this for a generic package, say $pkg, rather than
    main, should I use something like


    instead? Or are there better ways?

    *{ ${"${pkg}::"}{$_} }{CODE}

    seems to work, even though I had naively and erroneously assumed that
    the outer *{ ... } wouldn't have been necessary, but is even more
    verbose and clumsy...

    Michele Dondi, Nov 9, 2004
  14. Guest

    Anno Siegel Guest

    Uh, no. I'm not running them, that would be suicidal... Also,
    as you note, there's no telling what they return.

    "defined &foo" is special, it tests if a sub is defined (has code
    associated with it). It's the standard way of testing if a sub
    exists, I just adapted it to the situation, making use of the fact
    that a glob can be de-referenced like a ref. The glob_as_a_hash
    syntax you're using just didn't come to mind as readily, so I
    used the first thing that worked. How's that for the praxis of
    experience? :)
    Well... it works.
    That looks like an attempt to restrict the symref what's absolutely
    necessary. "$_", which went into the symref above, is now a respectable
    piece of data (a hash key). But you can't avoid a symref altogether
    (I don't think so), so why bother.

    Then again, it gains a little when the '::' is made part of $pkg (or
    never stripped off in the first place):

    *{ ${ $pkg}{ $_}}{ CODE}

    doesn't look half bad.

    Anno Siegel, Nov 9, 2004
  15. Guest

    Joe Smith Guest

    You are aware, I hope, that subs using wantarray() can return more
    than one type, depending on context (list, scalar, void).
    Joe Smith, Nov 10, 2004
  16. My fault, I plainly didn't know! Yet another bit of magic, I see...
    incidentally this may be yet another good reason not to use the &-form
    of sub call. E.g.:

    my $def;
    defined &{$_} and $def++ for \&sub1, \&sub2, \&sub3;

    will always give me $def==3, IIUC.
    [snip rest]

    TY for your helpful cmts.

    Michele Dondi, Nov 10, 2004
  17. () wrote in
    The 'ref' operator will tell you what class an object is a member of.

    There is no real way to list all the methods for a Perl class, because
    classes in Perl are allowed to (and sometimes do!) create methods on the
    fly, via the AUTOLOAD subroutine. A class can potentially have an
    unlimited number of methods, none of which are defined at compile time.

    Eric J. Roode, Nov 14, 2004
    1. Advertisements

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.