One additional thing to be aware of is that not all of the code entries you find in the symbol table will be methods of the class/object. That is, somebody could just put in a helper function in the package that you can't call as an object method.

That is, you could have stuff like this in the child package:

package SimpleExample; sub method_foo { my $self = shift; # ... bla bla bla ... my $arg = 42; my $intermediate_result = helper_function($arg); # ... bla bla bla ... } # ... sub helper_function { my ($arg) = @_; # ... bla bla bla ... }

Now guess what a simple symbol table scan will give you: you will get out both "method_foo" and "helper_function" as code entries in the symbol table. But you can't say SimpleExample->helper_function($bar). "helper_function" is just a normal function, not a method.

Solution: you will have to test any function names you got from the symbol table of the package if they can be called on the class/object. You do that by using the much underestimated "can()" method from package UNIVERSAL.

Ah, and before I forget it: obviously you will have to do a recursive symbol table scan to get all the methods for a given package, scanning the parents of a class/object as well.

Here is how something similar is done in Test::Unit::TestCase, part of the Test::Unit framework (coded by brother pdcawley, thanks again Piers!).

sub list_tests { my $class = ref($_[0]) || $_[0]; my @tests; no strict 'refs'; if (defined(@{"$class\::TESTS"})) { push @tests, @{"$class\::TESTS"}; } else { push @tests, grep { /^test/ && $class->can($_) } keys %{"$class\::"}; } push @tests, map {$_->can('list_tests') ? $_->list_tests : ()} @{"$class\::ISA"}; my %tests = map {$_ => ''} @tests if @tests; return keys %tests; }

(And yes, I have been there and messed it up. Thanks to Piers Cawley for educating me.)

Christian Lemburg
Brainbench MVP for Perl
http://www.brainbench.com


In reply to Re: Request for review: OO, inheritance, and a symbol table trick. by clemburg
in thread Request for review: OO, inheritance, and a symbol table trick. by maverick

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.