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

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.

Replies are listed 'Best First'.
Re^4: linting for undefined object methods
by aespen (Initiate) on Sep 01, 2009 at 22:53 UTC
    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.

        The linter would warn if the method name could not be located in any namespace, ie.
        [Thu Sep 3 10:38:06 2009] ajaxGetDRCFilesTable.cgi: subroutine call $ +drc->searchDirectory() does not refer to any defined sub. line 223
        This would catch the deadly typo that gets missed during test. If I get a free moment, I'll take a look at some of the approaches proposed here to do something for our situation. Thanks for the help.