Detecting sub/call mismatches?

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

Threaded View
I'm moving subs from one source file to another, and sometimes
renaming them according to a more unified naming convention, so
    OldName (while in package OldModule)
should all be changed to NewModule::NewName.

The problem, of course, is when I screw up a call to some version of
the old name, which (so far) has ended up as
    OldModule::OldName (that is, I overlooked it entirely)
    OldName (while in package OldModule; overlooked)
    NewName (while in package OldModule, so that's OldModule::NewName)
I've caught these by eyeball inspection and I'll go thru it again, but
I'm nervous.

In Perl, of course, you can't in general do a static "compile time"
check -- in principle, there could be a sub defined with eval, a
reference to a sub, a sub name generated by code, et cetera.

Nevertheless, even if I can't get perfection, I'd like to do some
static verification if it's possible -- a Perl lint, for those
familiar with the old C tool.  In practice, our code rarely does
obscure things.  All I've seen are package declarations alone on a
line, and "sub SomeName *{" starting in column 1, and calls to
SomeModule:SomeName, except within SomeModule, where we usually do
just SomeName.

Is there anything I can do to get a partial check?

I've thought of hacking together a script that reads source files to
look for package and sub declarations to generate a table of potential
definitions, and the uses are every word that is followed by a left
paren.  I could get some false results due to not following the proper
parsing (is there a module to parse Perl code?), like misunderstanding
quotation or comments.  But even if I find one error now instead of
several weeks from now when some obscure path is finally run, and get
a slew of bad hits, I'd be happier.

Tim McDaniel,

Re: Detecting sub/call mismatches?

On Tuesday, November 20, 2012 7:07:11 PM UTC-8, Tim McDaniel wrote:
Quoted text here. Click to load it

B::Xref might help  - perldoc B::Xref

Charles DeRykus

Re: Detecting sub/call mismatches?

Quoted text here. Click to load it

Interesting -- thank you for the pointer.

It's strange, though, that /^File / lines are so odd:

  Subroutine (definitions)

File ^E
  Subroutine (definitions)
      Package Moose::Error::Util
            &_create_error_carpmess  s26
            &create_error     s43
            &create_error_confess  s34
            &create_error_croak  s30
  Subroutine (definitions)

  Subroutine (definitions)


Tim McDaniel,

Re: Detecting sub/call mismatches? (Tim McDaniel) writes:
Quoted text here. Click to load it

You could try B::Lint.

Re: Detecting sub/call mismatches?

Quoted text here. Click to load it

Assuming your program will run through 'perl -c' without doing anything
untoward (this isn't given, but can be arranged), you can use B::Lint.

    ~% perl -MO=Lint -e'foo()'
    Nonexistent subroutine 'foo' called at -e line 1
    -e syntax OK

IMHO most of the checks Lint makes are annoying and useless, so you may
want to turn off everything except calls to nonexistent subs.

Quoted text here. Click to load it

There is PPI. It is not perfect (parsing Perl without executing it is
logically impossible) but it does a pretty good job.

Also, you need a test suite. Once you have tests that exercise all the
paths through your code, you can run the suite and then be reasonably
sure you won't get any more surprises.


Site Timeline