Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

OOP introspection

by Anonymous Monk
on Apr 02, 2021 at 21:21 UTC ( [id://11130739]=perlquestion: print w/replies, xml ) Need Help??

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

Is there a way to get all the hierarchy of the classes of an object? (No Moose etc,just classic OO Perl)
say A->B>C , examining C gives A and B as parents.

Also in the case of composition how can I find out which class depends on which class?
Or what kind of objects can be injected in the constructor of an other object?

Replies are listed 'Best First'.
Re: OOP introspection (inheritance)
by LanX (Saint) on Apr 02, 2021 at 21:28 UTC
    > Is there a way to get all the hierarchy of the classes of an object? (No Moose etc,just classic OO Perl) say A->B>C , examining C gives A and B as parents.

    @ISA is a package var, i.e. globally accessible.

    So start iterating over @C::ISA and continue recursively?

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

Re: OOP introspection (composition)
by LanX (Saint) on Apr 02, 2021 at 21:39 UTC
    > Also in the case of composition how can I find out which class depends on which class?

    That's a tougher one, because AFAIK does "classic Perl" only allow imports for "composition". Differing OO-frameworks might have differing approaches and builtin solutions for inspection.

    But you can iterate over all subs in the namespace° of a class and inspect in which module it was originally defined.

    There is a core module for that° Sub::Util (read the doc for subname ) ... or something like Sub::Identify from CPAN.

    edit

    °) This won't help you if the composition was done by changing AUTOLOAD , but I don't even know if this approach is even a thing in OOP (?)

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

    °) sorry I was wrong about that, Sub::Util is not implementing what Sub::Identify does. But the latter comes with a compact pure Perl implementation using the B backend to extract those informations. AFAICS it's the same approach like described in the book "Perl Hacks".

      could be that I totally misunderstood your question about composition as "composing" a class with roles

      compare

      https://perldoc.perl.org/perlootut#Roles

      vs

      https://perldoc.perl.org/perlootut#Composition °

      In case you meant the latter:

      This is extremely difficult in dynamically typed languages.

      You would of course parse the code for use of other classes and constructors named "new".

      But this would only give you a fragile approximation of dependencies at best, because of all the flexibility Perl offers.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

      °) which is very generally speaking and fuzzy

Re: OOP introspection
by Discipulus (Canon) on Apr 02, 2021 at 21:30 UTC
    Class::MOP ?

    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
Re: OOP introspection
by haukex (Archbishop) on Apr 03, 2021 at 08:32 UTC

    LanX has already pointed you to @ISA. Note that if this is about method resolution order, see mro, for example it provides a mro::get_linear_isa($classname) function that may be useful.

    Also in the case of composition how can I find out which class depends on which class? Or what kind of objects can be injected in the constructor of an other object?

    I'm not sure I understand, could you illustrate these questions with code?

      Indeed, using mro::get_linear_isa($class) is the right way for obtaining the full class hierarchy!
Re: OOP introspection
by perlfan (Vicar) on Apr 02, 2021 at 22:07 UTC
    I suppose one way to do it would be to go "up the chain"; utlizing SUPER (i.e., $self->SUPER::new + ref on the ancestor to get __PACKAGE__, it's reasonable to assume you could explore the turtles all the way up). Start with your initial blessed reference; recreate parent using my $father = $son->SUPER::new; use $father to recreated grandfather, so on and so forth. This example relies on each having new; but seems to reason it would work in Moo, Moose, and their elk.
      Aside from the reliance on a predictably-named constructor (->new), this also implicitly assumes single inheritance. I'm not sure that there's any practical way to get all the ancestors in a multiple-inheritance scenario other than iterating the @ISAs.
        I didn't consider multiple inheritenace. I suppose I need to play with SUPER to see what it does in that case.

      perlfan:

      If the system allowed additional upvodes, I'd give an extra one just for that last word. ;^)

      ...roboticus

      When your only tool is a hammer, all problems look like your thumb.

Re: OOP introspection
by hippo (Bishop) on Apr 03, 2021 at 10:21 UTC
    Is there a way to get all the hierarchy of the classes of an object?

    Sounds like it could be an XY Problem. Why do you want to know this?


    🦛

      I'm trying to get my head around the complexity of the huge XML::Compile namespace.

      Like I wanted to change the connection timeout from the default to 10 seconds.
      So there's XML::Compile::Transport::SOAPHTTP which does that,but then I was trying to figure out how that relates to the main XML::Compile::WSDL11 when doing the actual call with
      my $call = $wsdl->compileClient('GetStockPrice', ...);
      # at "run-time", call as often as you want (fast)
      my $answer = $call->(%request);
      

      how does the XML::Compile::Transport::SOAPHTTP relates to this call?How should I use it?
      eventually after sometime I used
      my $trans = XML::Compile::Transport::SOAPHTTP
        ->new(timeout => 500, address => $wsdl->endPoint);
      $wsdl->compileCalls(transport => $trans);
       
      # alternatives for simple cases
      $wsdl->compileAll('CALLS');
      $wsdl->compileAll;
       
      my $answer = $wsdl->call($myop, $request);
      
      and not using compileClient.

      but the point is, can I rely to something else than the documentation? Would introspection be useful in this case?

      automating documentation of classes hierarchy/ancenstry?

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (4)
As of 2024-04-25 14:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found