Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Class/Object Method Lister

by stvn (Monsignor)
on Jan 19, 2004 at 02:03 UTC ( [id://322256]=CUFP: print w/replies, xml ) Need Help??

It's maybe the start of an automated OO documentation tool. It provides 2 views of your class. The first is the flat view, where it lists all the methods available to an object implemented and inherited. The second is the expanded view, which lists all the implemented methods, then climbs down the classes inheritance heirarchy doing the same for each class (and tabbing it in appropriately too).

The example given in this script is to list the IO::File class, which has a deep enough heirarchy to show how this works.

#!/usr/bin/perl use strict; use warnings; no strict 'refs'; ## ------------------------------------------------------------------ # if you want certain methods ignored, # put their names in this string and it # will get weeded out with a reg-ex. my $IGNORE = ""; sub getClassMethodList { my $class = shift; return grep { !/^($IGNORE)$/ && defined &{"${class}::$_"} } keys %{"${class}::"}; } sub getCompleteClassMethodList { my ($class) = @_; my @methods = getClassMethodList($class); push @methods => map { getCompleteClassMethodList($_) } @{"${class}::ISA"}; return @methods; } ## ------------------------------------------------------------------ sub printExpandedClassView { my ($class, $tab_count) = @_; $tab_count ||= 0; if ($tab_count) { my $t = ("\t" x $tab_count); print "${t}$class\n"; print "${t}-------------------------------------------\n$t"; print join "\n${t}", getClassMethodList($class); print "\n"; } else { print("$class\n"); print "-------------------------------------------\n"; print join "\n" => getClassMethodList($class); print "\n"; } map { printExpandedClassView($_, $tab_count + 1) } @{"${class}::ISA"}; } sub printFlatClassView { my ($class) = @_; print("$class\n"); print "-------------------------------------------\n"; my %method = map { $_ => 1 } getCompleteClassMethodList($class); print join "\n" => keys %method; print "\n"; } ## ------------------------------------------------------------------ use IO::File; printFlatClassView("IO::File"); print "\n"; printExpandedClassView("IO::File"); print "\n"; 1;
-stvn

Replies are listed 'Best First'.
Re: Class/Object Method Lister
by rnahi (Curate) on Jan 19, 2004 at 06:05 UTC

    To make a general purpose lister, replace the last lines (from "use IO::File" to the end) with this:

    my $module = shift or die "module name required"; eval "require $module" or die "$@\n"; printFlatClassView($module); print "\n"; printExpandedClassView($module); print "\n";

    Then, you can run the script with the module name on the command line.

    $ method_lister IO::File
Re: Class/Object Method Lister
by markov (Scribe) on Jan 19, 2004 at 10:20 UTC

    What you describe is precisely what I was looking for myself, a while ago. When multiple levels of inheritance exist, it is terribly hard to figure-out what you can do with an object...

    With your small script, you can figure-out what functionality is available... but you still have to go through the manual pages to figure-out the exact meaning of the methods found. IMO it is mostly solving a documenting problem.

    Therefore, I have create a documentation tool which helps you with that. Have a look at the OODoc documentation to see how this cross-reference looks like... and it is only a small extension to POD which produced those pages (both in POD and optimized HTML).

      Markov,

      I looked at your OODoc system. I like certain aspects of it, although the removal of documentation from the source was not one. Not that having documentation in source makes it any more likely that it will be read and/or updated, but having it all in one place tends to help. Maybe you should consider placing all you markup inside "=pod" and "=cut" directives or insisting the user places the documentation after the __DATA__ tag. Either one would allow you to keep your POD extensions intact.

      But I do agree with you that POD is very limited/limiting. I myself have created an alternate POD. I call it XOD actually. I built it to be "extensible" POD, much like XML is to HTML, XOD is to POD. XOD of course isn't the best name for it (as the acronym doesn't work), but it is the name of the evil villian in the original Superman movie (although that was surely spelt with a Z).

      XOD has only a few reserved "tags" which perform special functions in the parser. Things like including files and slurping verbatim text. Other than that its "tags" are up to you. It will parse into a tree-based structure, that can be transformed with a simple Visitor style object. Becuase of this, you can really do anything you want with it in terms of dialects (again, just like XML). It has 2 kinds of "tags". Containers, which start with a "=whatever" and always end with an "=end". And single elements, which are denoted by a colon at the end of the "tag" name, like this; "=element:". It also picks up lines of plain text, and processes embedded "<>" structures.

      The best way to illustrate this all though, is an example. Here is a quick snippet of some XOD code:

      =xod =head1: Testing Hello there B<World>, I<how are you B<?>> =list =item: L<test> =item: other item =end =cut
      And here is the tree structure that will convert to:
      XOD::Command (head1:) XOD::Text (Testing) XOD::Paragraph XOD::Text (Hello there ) XOD::Modifier (B) XOD::Text (World) XOD::Text (, ) XOD::Modifier (I) XOD::Text (how are you) XOD::Modifier (B) XOD::Text (?) XOD::Command (list) XOD::Command (item:) XOD::Modifier (L) XOD::Text (test) XOD::Command (item:) XOD::Text (other item)

      This isn't released yet (its part of a much larger framework I am developing at my company (up too 125 classes now and almost 14,000 lines of code). If you are interested in knowing more, msg me and we can talk.

      -stvn
        I looked at your OODoc system. I like certain aspects of it, although the removal of documentation from the source was not one.

        ... then I have to create an option to leave the docs in. However, when real pod is created, you do not want the meta-pod in X.pm conflict with the produced pod in X.pod.

        Besides, I heard too many people say that they do not want pod merged with the code because it would make compilation slower. Now those people have no reason not to write docs anymore.

        My choice was for logical markup i.s.o. visual markup, for instance '=method' and '=option'. Does XOD do more than syntax parsing?

Re: Class/Object Method Lister
by graff (Chancellor) on Jan 19, 2004 at 04:55 UTC
    Very cool. It would be neat to do some additional "formatting" on the output, e.g. to provide stubs for common pod headings, or whatnot.

    It would also be neat if the module being listed in this way could be given as a command-line parameter. But I couldn't figure out how to do that... Even though it works to say "require IO::File" instead of "use IO::File", it does not seem to work with "require $ARGV[0]" or anything of that sort (putting "IO::File" on the command line).

Re: Class/Object Method Lister
by Anonymous Monk on Jan 19, 2004 at 07:07 UTC
    Module::Dependency::Grapher Module::Info Devel::ModInfo

      While these are all interesting modules, they all look pretty complex, and from what I can tell they read and parse the files themselves. At least the Module::Dependency suite and the Module::Info suite do, i cant figure out how the Devel::ModInfo suite works other than it has alot of XML and sounds frightenlingly like JavaDocs. Parsing can get quite hairy, i can already see where code in Module::Dependency had to branch for cases of "use base". My script (which is really just a quick one off, not a full system like these) uses the symbol table, which tends to be a much more reliable means of tracking inheritance and methods, since you are pretty much assured that if its in the symbol table, its there.

      -stvn

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (6)
As of 2024-04-24 08:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found