in reply to Re: linting for undefined object methods
in thread linting for undefined object methods

We are using a simple, restrictive OO methodology which should be fairly well lintable at compile time. All methods are known at compile time. We are not using perl's AUTOLOAD feature or any other sort of dynamic method generation. All objects are created with a call to CLASS->new() (no dynamic re-blessing) and the class hierarchy is contained in @ISA. I guess this is too much of a corner case for support in the general B::Lint module, but the bottom line is we miss catchable stuff at compile time that causes real problems. Maybe I should write a plugin for Lint for this sort of situation.
  • Comment on Re^2: linting for undefined object methods

Replies are listed 'Best First'.
Re^3: linting for undefined object methods
by ikegami (Patriarch) on Sep 01, 2009 at 22:23 UTC

    By having the linter make the giant assumption that all subs are methods, that tells you a bit about $self, but not enough. It only helps determine that cases such as the following aren't problems:

    { package Base; sub x { ... } } { package Child; our @ISA = 'Base'; sub y { shift->x } }

    However, it doesn't help determine that something is a problem. For example, is there a problem in the following?

    package Package; sub y { shift->x }

    No, turns out package Package is just a role:

    { package SomeRole; # Implementor must provide y sub y { shift->x } } { package Class; our @ISA = 'SomeRole'; sub x { ... } }

    But that's not the real test. How often do you call a child method that doesn't exist? I expect the majority of problems to be in code such as the following:

    sub some_method { my ($self, $arg) = @_ ... $arg->other_method(); ... }
    or
    sub some_method { my ($self) = @_ ... $self->attribute->other_method(); ... }

    The linter knows absolutely nothing about the class or object whose method other_method is being called, so it has no idea if other_method exists for that class or object.

      This all makes sense to me, but given the constraint of statically defined methods, would it be reasonable to have the linter locate method names in known namespaces or else give warning? For method invocations on references where the class cannot be known at compile time, this would at least catch the 'method doesn't exist anywhere in a known namespace' type of error. I understand that this is not useful in the general case, but with 100K lines of code strewn over 200 files and classes with fairly verbose method names it sure would be nice to know that
      $dataView->htmTable('edit');
      will fail when the method is actually called
      sub htmlTable { }
      When $dataView's class cannot be known, having 'htmlTable' exist somewhere in the application namespace is clearly no guarantee of success at runtime... but missing the 'htmTable' bug is a *definite* guarantee that there will be a problem. A lint check, imperfect as it may be, still seems to offer value in my case.

        This all makes sense to me, but given the constraint of statically defined methods, would it be reasonable to have the linter locate method names in known namespaces or else give warning?

        So if any namespaces contains a sub, all classes are considered to define that sub? You could do that. It should help against typos.

Re^3: linting for undefined object methods
by LanX (Saint) on Sep 01, 2009 at 22:33 UTC
    Thanks for explaining the "corner cases".

    Maybe I should write a plugin for Lint for this sort of situation.

    Maybe you should consider to have a look into PPI for static parsing and/or B::Xref and something like B::Concise for parsing after compilation.

    Cheers Rolf

    UPDATET distinction between static and compilation parsing