Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Re: Can a Perl module "inspect" itself and provide details about methods and parameters?

by stevieb (Canon)
on Sep 21, 2019 at 21:50 UTC ( [id://11106516]=note: print w/replies, xml ) Need Help??


in reply to Can a Perl module "inspect" itself and provide details about methods and parameters?

I think it'd be a futile effort to try to sort out what params each subroutine accepts because they can come in and be handled in a myriad of ways.

However, using my Devel::Examine::Subs, you can at least get info about subroutines within a file, module or directory.

Here's a code snip. In this case, I'm in a distribution directory (my Mock::Sub repository):

use warnings; use strict; use Devel::Examine::Subs; my $des = Devel::Examine::Subs->new(file => '.'); my $data = $des->all; for my $file (keys %$data){ print "$file:\n"; for my $sub (@{ $data->{$file} }){ print "\t$sub\n"; } }

Output:

lib/Mock/Sub/Child.pm: new _mock remock unmock called called_count called_with name reset return_value side_effect _check_side_effect mocked_state _no_warn DESTROY _end lib/Mock/Sub.pm: import new mock mocked_subs mocked_objects mocked_state DESTROY __end

You can even get info about each sub. This example is reading just a single file (but it does work with directories and modules, it's just a bit different to extract the data. Docs contain this info.

use warnings; use strict; use feature 'say'; use Devel::Examine::Subs; my $des = Devel::Examine::Subs->new(file => 'lib/Mock/Sub.pm'); my $subs = $des->objects; for my $sub (@$subs){ say $sub->name; say "\tstart line: ". $sub->start; say "\tend line: " . $sub->end; say "\tline count: " . $sub->line_count; # the following would list out the entire code block # for the sub. Commented out for output brevity #say "\tsub code:"; #say "\t\t$_" for @{ $sub->code }; }

Snip of output:

import start line: 14 end line: 17 line count: 4 mocked_objects start line: 74 end line: 82 line count: 9 new start line: 18 end line: 26 line count: 9 DESTROY start line: 100 end line: 101 line count: 2 __end start line: 102 end line: 102 line count: 1 mocked_state start line: 83 end line: 99 line count: 17 mocked_subs start line: 62 end line: 73 line count: 12 mock start line: 27 end line: 61

Works on in-memory modules as well. Send the module name to the file parameter. If the module is installed, we'll load it and read from there:

use warnings; use strict; use Devel::Examine::Subs; my $des = Devel::Examine::Subs->new(file => 'Logging::Simple'); my $subs = $des->all; print "$_\n" for @$subs;

Output from my Logging::Simple distribution module:

BEGIN _sub_names new level file name timestamp levels labels display print child custom_display fatal _generate_entry _levels _log_only

Note that the _end() methods are simply placeholders; they allow my editor to fold all of my POD up into the last subroutine so when I go to bottom of the current file, it doesn't take me to the end of my POD.

You could also use PPI to do the same thing. That's what my distribution uses, and added a whole slew of things around it.

  • Comment on Re: Can a Perl module "inspect" itself and provide details about methods and parameters?
  • Select or Download Code

Replies are listed 'Best First'.
Re^2: Can a Perl module "inspect" itself and provide details about methods and parameters?
by Br'er Rabbit (Novice) on Sep 21, 2019 at 22:19 UTC
    @Stevieb

    > I think it'd be a futile effort to try to sort out what params each subroutine accepts because they can come in and be handled in a myriad of ways.

    This part is just sad: if objects were self-documenting, then they wouldn't have to rely on the existence of (good) external documentation.

    "If I ever write one", (he wrote, pompously) "I'll sure gladly provide everything everybody would want to know."

    Your code will nevertheless be a Big Help in filling in some holes about What's Actually Callable.

    Thank you.

      "This part is just sad: if objects were self-documenting, then they wouldn't have to rely on the existence of (good) external documentation."

      When I'm writing against an object, my IDE pops up with a list of valid methods to choose from, and autocompletes if I desire. To boot, once I've typed in the method name, it'll display to me what arguments the method (or function) accepts. Now, if the function/method is accepting a single hash for example, there's no way to know at all what key/value pairs are used within that hash. However, if all of the parameters are individual scalars in a specific order, it will list those (with their names included).

      Here's an image showing the IDE displaying a list of available methods to an external class (works on objects all the same).

      ...and here's an image showing the parameters for an object's method.

      A good IDE can help tremendously, especially when you're working with numerous classes at the same time. You can CTRL-click on any variable, method, function or anything, and you can make one click to go to the definition of it immediately.

      Rarely do I need to view documentation online, or the command line. Typically in Perl, we gather up all of our parameters at the top of each subroutine, so being able to go directly to the definition of a sub makes it trivial to see exactly how params are being used.

      With ImageMagic—since that was the genesis of the thread(s)—you have an added complication. You have to document, introspect the Perl interface/bindings and the C libs beneath. Documentation and code are not, and can never be, the same any more than even simple math could be. I don’t think it’s particularly sad. It is what it is. Perl’s deep flexibility, including lack of types, also precludes a perfect solution, maybe even a consistently decent one, to this kind of introspection. Temporarily suspending the excellent, at least interesting, ideas of affordance and literacy in code; a tool that is also its own manual will end up cumbersome and awkward as both. XML and XSLT come to mind for me here.

      @AllMonksWhoTookTheTime

      Thank you, esp. for explaining what must seem obvious to you by now. (I hope this thread survives: at my age, I'm sure I'll be back to read it... ;^) )

      Note @Stevieb: Re: Devel::Examine::Subs had to install a good number of other modules first, so out-of-touch was my CPAN, and now am only failing t/42 and t/43. Clearly, from you own observation, presaging others', about the "uncertainty" associated with retrieved parameters, the pressure to have and use the tool is off. I'll give it a few more good tries, but will otherwise take the hint and move on and look for my answers in the source. Thank you.

Log In?
Username:
Password:

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

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

    No recent polls found