lcpan tips 009: Finding subroutines

About this series: a collection of short, daily blog posts about lcpan tips/recipes. Some posts will also end up in the upcoming App::lcpan::Manual::Cookbook POD to be included in the App-lcpan distribution.

About lcpan: an application to download and index a mini CPAN mirror on your local filesystem, so in effect you will have something like your own CPAN with a command-line tool (or perl API) to query and extract information from your mirror. I find it perfect for my own personal use when working offline.

About the feature

As of version 0.78, lcpan supports indexing of subroutines. This is still an experimental version, and not enabled by default. To enable it, you’ll have to update your index using:

% lcpan update --no-skip-sub-indexing

Or, you can also put this in your ~/lcpan.conf:


What’s implemented so far is also very basic. lcpan parses each indexed module’s .pm file using Compiler::Lexer (I skip PPI because I’d reckon it would be rather annoyingly slow. There is also Perl::Lexer but the module’s POD gives a hard warning against using it and I don’t know if it can execute Perl code during lexing, which would be unsafe.) Subroutine declaration is searched and the subroutine name collected, along with the declaration’s line number in the source file.

I haven’t skipped any special subroutine names (e.g. new, DESTROY, AUTOLOAD) except the ones prefixed with underscore. I haven’t parsed any subroutine signature (either from the perl 5.20+ new signature feature, or from the POD). I also haven’t tried to guess whether a subroutine is method/static method/regular function/role/all of them. And lastly, there is no support yet for things like Moose or other fancy modules like Function::Parameters (which lets you define subroutine using the fun keyword).

Searching for functions

I also don’t know yet how useful this feature is going to be. I know that in one or two occasions I’m looking to use a function from a CPAN module, but I don’t remember the module’s name. I remember the function’s name but not exactly. In that case, I can try searching the function:

% lcpan subs rgb -l --query-type name ;# search any function that contain the string 'rgb' in its name
% lcpan subs 'convert%color%' -l --query-type name ;# search using SQL LIKE expression
% lcpan subs 'set_position' -l --query-type exact-name ;# search for exact name

And basically that’s about it.

I plan (and am also looking for ideas on how) to make this more useful. For example, indexing the calling/using relationship between subroutines, so you can know which subroutines are most popular/used. Or, creating statistics of the average number of subroutines per module, the average subroutine name’s length, the average subroutine’s length (in number of lines), and so on. Ideas welcome.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s