Finding Unused Subroutines, but with PPI

Can I find all unused Perl subroutines with PPI? Ovid tried it with a quick shell script, which is probably good enough for his purposes, and certainly shorter than my solution.

I don't know if I've covered all of the cases, but it seems to mostly work.


Thanks for this. I started a messy project for general discovery and graphing for legacy CGI projects which is here:

Inspired by this and PPI in general, I'm thinking about taking another run at it. Thanks again, Hugh Barnard

There's always perlcritic --single UnusedPrivateSubroutines, if its assumptions are what you want.

If not, this policy might be a good starting point to roll your own. The policy uses a Perl::Critic::Document rather than a PPI::Document, but the former is easily manufactured from the latter.

(Sorry I'm not good at English)

Thank you for your good post, always.

I tested the above code and it seems that the code fails to catch sub calls in the form of "foo()".

And, if target code has no sub call form "&...", this script dies with:

Can't use string ("") as an ARRAY ref while "strict refs" in use at D:\Temp\ line 42.

Thank you, Brian! This will be a very useful addition to my toolbox.

I tried to run your latest revision and it appears that it still does not recognize any call that uses parentheses, e.g. fubar() ?

Dumping the output of

$_[1]->snext_sibling->isa( 'PPI::Structure::List'
gives me an undef which possibly why @list will always be empty?


Nice, It would be nice to see it as part of PPIx::EditorTools.

Would you do it? If not, do you mind if I add it?

I just noticed this. It's a lovely bit of code. You mention that it's longer than mine, but it has a couple of strong advantages: it handles comments correctly and can easily be extended to other uses.

Leave a comment

About brian d foy

user-pic I'm the author of Mastering Perl, and the co-author of Learning Perl (6th Edition), Intermediate Perl, Programming Perl (4th Edition) and Effective Perl Programming (2nd Edition).