Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

How to identify available subclasses?

by olliecook (Initiate)
on Sep 08, 2008 at 13:45 UTC ( #709756=perlquestion: print w/replies, xml ) Need Help??

olliecook has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

Given a tree of modules that are available to the interpreter:
A A::B A::B::C A::B::D A::B::E A::C::D A::C::E
Is there a programmatic way to identify the names of modules that are children below a certain point in the tree, say "A::B" or just "A"?

My specific question is I have a number of log parsers which inherit from a superclass. I would like the superclass to 'offer' a log line to each parser (dynamically determined at run-time) as a test to see whether that parser can handle files in that format. For this to work, I need to be able to identify what subclasses exist under the superclass.

It would be possible to traverse each element of @INC, but that strikes me as rather ugly.

Is there a better way?

Thanks,

Ollie

Replies are listed 'Best First'.
Re: How to identify available subclasses?
by themage (Friar) on Sep 08, 2008 at 14:07 UTC
Re: How to identify available subclasses?
by moritz (Cardinal) on Sep 08, 2008 at 13:56 UTC
    It would be possible to traverse each element of @INC, but that strikes me as rather ugly.

    It is ugly, and it's not enough. With that approach you get all parent classes, not all subclasses. Instead you'd have to walk the symbol tables and check their @ISA arrays - even uglier.

    Generally it's better to use a different approach, for example register each base class with the parent:

    { package Your::Parser; my @parsers; sub register { push @parsers, $_[0]; } } { package Your::Sub::Parser; our @ISA qw(Your::Parser); __PACKAGE__->register(); }
Re: How to identify available subclasses?
by Fletch (Bishop) on Sep 08, 2008 at 14:01 UTC

    Actually you'd want to walk the symbol table looking for @ISA in various packages which refer back (directly or indirectly) to your superclass, not @INC. But it sounds like you're trying to do an abstract factory pattern, in which case a cleaner mechanism would be to provide a callback in the top level factory package which implementing subclasses call to register themselves (e.g. in your MyLogFactory::Parser::Foo module it calls MyLogFactory->registerParser( 'Foo' => 'MyLogFactory::Parser::Foo' );, which then makes MyLogFactory->parserFor( 'Foo' ) return an instance of MyLogFactory::Parser::Foo).

    (Granted in perl you could have my $parserClass = 'MyLogFactory::Parser::Foo' and $parserClass->new straight in the calling code and would work too . . .; unlike (say) C++ you don't need to register a hard pointer to the constructor since the client code can dynamically instantiate itself with just the package name :)

    Update: tweaked trailing parenthetical's wording to clarify.

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

Re: How to identify available subclasses?
by betterworld (Curate) on Sep 08, 2008 at 13:59 UTC

    You can have the child classes register themselves with the superclass. One easy way to do this is via the superclass'es import subroutine, which is triggered by use.

    See my recent node Re^2: How not to hardcode a package name? for an example.

Re: How to identify available subclasses?
by DrHyde (Prior) on Sep 09, 2008 at 09:51 UTC

    If your subclasses are already loaded, then you can use Class::CanBeA to identify which ones are subclasses of a given class.

    Simply looking at filenames in @INC ain't gonna do the job right in general. For example, it might tell you that Class::DBI::ClassGenerator is a subclass of Class::DBI when it isn't - it even contains the test "use base 'Class::DBI'" just to confuse matters.

Re: How to identify available subclasses?
by Arunbear (Prior) on Sep 09, 2008 at 10:49 UTC

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://709756]
Approved by Corion
Front-paged by Tanktalus
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (4)
As of 2022-10-04 07:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My preferred way to holiday/vacation is:











    Results (16 votes). Check out past polls.

    Notices?