Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

getting a list of all subclasses of base class x

by hexcoder (Hermit)
on Jul 08, 2008 at 16:20 UTC ( #696249=perlquestion: print w/ replies, xml ) Need Help??
hexcoder has asked for the wisdom of the Perl Monks concerning the following question:

Dear monks,
I wonder how I can get a list of all loaded subclasses of a given base class x from a foreign module.
I thought this must be a FAQ, but I could find nothing in the FAQs, Conway's book 'Object oriented perl' and the cookbook.

I want this because I want to register all of them at initialization time. Currently I use an ugly hardcoded list. Since my module should be independent of the foreign module, I want to replace the hardcoded list with a dynamically retrieved one. Then all additions/deletions of subclasses would be tracked automatically.

The debugger has a hash %DB::sub containing all subroutines in scope, so in the debugger I could probably use something like

require 'perl5db.pl'; my $base_class = 'x'; my @subclass_list = grep { $_->isa($base_class) } keys %DB::sub;
How can I get this list without the debugger module?

Thanks very much, hexcoder

Comment on getting a list of all subclasses of base class x
Select or Download Code
Re: getting a list of all subclasses of base class x
by moritz (Cardinal) on Jul 08, 2008 at 16:35 UTC
    You can try to walk the symbol tables (described in perlmod) and check @ISA in each package.

    But in general it's a sign of a bad design if you have to know about subclasses, because you do subclassing specifically to enable a functionality that wasn't intended when writing the super class.

      I want to process the token stream generated from PPI.
      So I want to enumerate and store each of its token types.

      I agree with your design objection, so I asked Adam Kennedy, if there is a method to list all such token classes in PPI. I will see what he suggests...

        http://search.cpan.org/src/ADAMK/PPI-1.203/lib/PPI/Token.pm
        #!/usr/bin/perl -- use strict; use warnings; use PPI::Token; print $_,$/ for map { s/\.pm//; s~/~::~g; $_; } sort grep /Token\W/, keys %INC; __END__ PPI::Token PPI::Token::ArrayIndex PPI::Token::Attribute PPI::Token::Cast PPI::Token::Comment PPI::Token::DashedWord PPI::Token::Data PPI::Token::End PPI::Token::HereDoc PPI::Token::Label PPI::Token::Magic PPI::Token::Number PPI::Token::Number::Binary PPI::Token::Number::Exp PPI::Token::Number::Float PPI::Token::Number::Hex PPI::Token::Number::Octal PPI::Token::Number::Version PPI::Token::Operator PPI::Token::Pod PPI::Token::Prototype PPI::Token::Quote PPI::Token::Quote::Double PPI::Token::Quote::Interpolate PPI::Token::Quote::Literal PPI::Token::Quote::Single PPI::Token::QuoteLike PPI::Token::QuoteLike::Backtick PPI::Token::QuoteLike::Command PPI::Token::QuoteLike::Readline PPI::Token::QuoteLike::Regexp PPI::Token::QuoteLike::Words PPI::Token::Regexp PPI::Token::Regexp::Match PPI::Token::Regexp::Substitute PPI::Token::Regexp::Transliterate PPI::Token::Separator PPI::Token::Structure PPI::Token::Symbol PPI::Token::Unknown PPI::Token::Whitespace PPI::Token::Word PPI::Token::_QuoteEngine PPI::Token::_QuoteEngine::Full PPI::Token::_QuoteEngine::Simple
        I want to process the token stream generated from PPI. So I want to enumerate and store each of its token types.

        Maybe you can enumerate them lazily as you encounter them? Something along these lines:

        use Memoize qw(memoize); memoize qw(number_for_class); sub number_for_class { state $i; return ++$i };
Re: getting a list of all subclasses of base class x
by pc88mxer (Vicar) on Jul 08, 2008 at 16:52 UTC
    I want this because I want to register all of them at initialization time.
    I would look for a way to have the classes register themselves at initialization.

    Are the subclasses using use base to set their @ISA array? Can you modify the subclass code? More details could yield more answers...

      thanks,
      the problem is, I want to do some analysis based on PPI generated tokens and PPI does not know my application. So the classes are sort of cast in stone and out of my reach.

      I thought it would be best, if PPI would offer a method to deliver a list of all token classes that it is using. So, all clients could ask the service providing module, if they need to.
      However that does not seem to be the case, so I am looking for something else.

Re: getting a list of all subclasses of base class x
by stvn (Monsignor) on Jul 08, 2008 at 18:26 UTC

    This should work

    my @subclasses = Class::MOP::Class->initialize('x')->subclasses;

    -stvn
      Thanks very much!
      ++

      it did work and it is very elegant!

      If you are interested, I am working on a policy for perlcritic to detect cut-and-paste regions (thats is repitition of code fragments). The full class names of the token types of PPI are too long to store, so I map them to small numbers.

        hehe - you're right, that should be:

        BEGIN { my @subclasses = Class::MOP::Class->initialize('x')->subclasses }
        ... much better now.

        -stvn

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://696249]
Approved by kyle
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (7)
As of 2014-09-01 23:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite cookbook is:










    Results (18 votes), past polls