eXile has asked for the wisdom of the Perl Monks concerning the following question:

One thing I'd like to have in perl is a syntax checker that takes into account object-methods. AFAIK object methods are not checked during compile time but caught runtime. The best solution is having a good test-suite for your code, but I keep wondering if there are syntax checkers that take into account object-methods. Does anybody know if there are any? If not, I'd like to try and write one. For that I at least have to take into account inheritance and AUTOLOAD, anything else? Am I completely missing the point here?
  • Comment on syntax error checking on object methods

Replies are listed 'Best First'.
Re: syntax error checking on object methods
by samtregar (Abbot) on Nov 01, 2004 at 03:51 UTC
    I don't think anything like this exists, but it certainly sounds useful to me. It also sounds really, really hard to write! Consider this code:

    my $obj = some_func($some_arg); $obj->method();

    It won't be easy to figure out what class to inspect for method(). The class of $obj may depend on $some_arg, which itself might come from some obscure source. Since Perl is a late-binding language intuiting the class for any given variable in the general case is going to be very hard.

    -sam

      Not to mention cases where the method name itself is dynamically computed at runtime.

      my $method = $phase_of_moon eq 'waxing' ? "discombobulate" : "vreemflitzel"; $obj->$method( $price_of_tea_in_china );
        I'd have missed both cases yes, so it's good I asked and I appreciate your answers. Maybe a full syntax checker on this is too much to desire, but a simple one that takes into account common cases where objects and methods are easily recognizable might not be that hard. In the long run a full syntax checker (if even possible) sounds like a good thing to have to me.
Re: syntax error checking on object methods
by ikegami (Patriarch) on Nov 01, 2004 at 06:03 UTC
    AFAIK object methods are not checked during compile time but caught runtime.

    That's the case for all subs, not just methods:

    >perl -e "$|=1; print 'this is runtime',$/; test();" this is runtime Undefined subroutine &main::test called at -e line 1.

    It's a requirement because of perl's dynamic nature. What if I had done
    *test = \&testing;
    or
    eval "sub test { return $var }";
    earlier on in the code? If the check were to be done at compile time, test() would incorrectly be labeled as an error.

    There's also the opposite case to consider, the case where the check passes even if the function doesn't exist, such as in
    $func = 'test'; &$func();

    Methods complicate things further. $obj->method() depends on the value of ref($obj) when that code is reached (run-time), the current (run-time) value of @ISA in a number of packages, and whether method currently (run-time) exists in a number of packages.

    And then, there are modules with AUTOLOAD...

Re: syntax error checking on object methods
by fergal (Chaplain) on Nov 01, 2004 at 10:34 UTC
    What I've been thinking about doing is hijacking the pseudo-hash syntax and using it for this. So if you did
    my Animal $spot = Dog->new; $spot->Reproduce; # fine $spot->DriveToWork # not OK some_other_function_that_returns_an_object()->method # ignore this
    I was thinking of using the B framework to get access to the parsed code. In a very simple implementation you would wander around the parsed code, looking for methods called directly on a variable, find out that the variable is a lexical declared as my Animal and end up checking Animal->can("Reproduce") and Animal->can("DriveToWork"). In a more sophisticated implementation, instead of using can, the method information would be held in say $Animal::INTERFACE and could also include info about method arguments or other useful stuff.

    Objections:

    • AUTOLOAD methods. These are OK as long as you can supply the list of possible valid methods. If you can't provide that list then static checking is probably not suitable for that class anyway. Even if the list of methods is large/infinite you could always provide a function that says yes or no to a particular method name.
    • Things like some_function()->Reproduce. To which I say, if you want real static checking, don't use Perl (5).

    I had a quick look at B last weekend and it looks like it should be possible by navigating through a B tree of opcodes looking for the method calls but it could be a lot of work to write the code because you need to cater for each opcode (athough most of the time you're just ignoring them I think).

    If anyone else fancies a challenge...