Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Compile-time/Auto-test method checking?

by Cybris (Sexton)
on Jun 26, 2009 at 08:28 UTC ( [id://774962]=perlquestion: print w/replies, xml ) Need Help??

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

Oh holders of Perl wisdom, this humble programmer seeks to know if a very nice feature of statically-typed languages is somehow possible in Perl: compile-time checking of the existance of class methods.

My problem: class hierachies sometimes need to be changed. This can include renaming/moving of packages, renaming of methods, and changing method parameter requiries. In statically-typed languages this is a relatively easy process, because the compiler will tell me if I have forgotten to change a method call somewhere - the incorrect method just doesn't exist in that class.

This leads to very nice features in IDEs like Netbeans, where simple renaming of classes, methods, or variables can be totally automated. Moreover, if I change the method prototype/parameter list, the IDE just tells me where I have to correct the calls, and I can correct my code quickly.

With a dynamically typed language like Perl, I assume this is very difficult to automate.

My question: Are there Perl tools that can automatically rename classes and methods, or even just display where I used a specific class or method name in an object? find|grep just doesn't cut it if a method name is too generic. Even worse, if I forget changing a method call, this will only become apparent at runtime, or if I have written enough tests. When I work on an existing project without tests, a simple perl -c is just not enough to check for such errors.

I realize such a tool is not easy to program, because method declarations are not only found in the source, but methods can be created at runtime (e.g. automated accessor method creation). Perhaps there is a tool/module that can collect package method names during runtime, and use that information to analyze the source and tell me where I called a method for which no declaration can be found?

Whenever I switch from a Java project to a Perl project, this problem arises. I forget to check for stuff in Perl that javac does automatically for me. I realize this is not a fault of Perl, but a result of the dynamic typing paradigm. But I have to switch languages from time to time, and would like to have more fun with Perl.
  • Comment on Compile-time/Auto-test method checking?

Replies are listed 'Best First'.
Re: Compile-time/Auto-test method checking?
by perrin (Chancellor) on Jun 26, 2009 at 15:09 UTC
Re: Compile-time/Auto-test method checking?
by mzedeler (Pilgrim) on Jun 26, 2009 at 12:37 UTC
      Most likely using the generic out of the box solution: ctags!

      Cheers Rolf

Re: Compile-time/Auto-test method checking?
by Anonymous Monk on Jun 26, 2009 at 08:56 UTC
      Thanks, this helps for renaming packages/classes. What about methods?
Re: Compile-time/Auto-test method checking?
by ELISHEVA (Prior) on Jun 26, 2009 at 13:13 UTC

    It isn't the perfect solution, but my best friend when it comes to changing parameter list and/or renaming Perl methods is the bash command:

    find ... -print0 | xargs -0 grep 'mymethodname' -or- find ... -print0 | xargs -0 grep -l 'mymethodname'

    I use the first when I want to find all the files and lines containing my method name. I use the second when I just want to see which files have such lines. If you aren't familiar with the commands:

    • find recursively searches for files. It has a rich set of options you can use to screen out files you aren't interested in. The -print0 option uses the null character to separate file names so you don't have to worry about quoting file names with spaces.
    • xargs passes the file list produced by find to grep. The -0 argument tells xargs to expect a null delimited file list.
    • grep - most likely you are familiar with this, but it selects lines containing a regex you provide. If you only want to see the file names, but not the lines, use the -l option.

    With all the find options, the command line can be quite long so I usually run it in a shell where I can keep history. That way I can simply recall the command via history, changing the method name as needed.

    Best, beth

Re: Compile-time/Auto-test method checking?
by LanX (Saint) on Jun 26, 2009 at 13:28 UTC
    The only¹ static approach I can think of is to restrict/enrich an object model in a way to define the methods statically.

    That means you can extend each class you use with information (eg an array or flagging them with attributes) about the method names.

    Then you can get the information which classes use which methods without running the class-code.

    Well you can easily do this with your own code... and I suppose you don't plan changing method names of foreign classes...

    BUT then you still have the problem to identify statically which class an object belongs to. An object in Perl is just a blessed reference to a data structure. A reference might have been created from somewhere without any "new class" syntax in the same file to parse.

    So you have to enrich your code with type-declarations (should be possible with attributes)

    So it's possible (you will be mimicking the mechanisms of static languages) but is this still perl???

    There are plenty of discussions of this in Perlmonks (search for static parsing and ppi), you might want to check if IDE-extensions like perlysense for emacs or padre already provide any automated help.

    Cheers Rolf

    UPDATE: (1) reliable

        > Module::Inspector, Class::Inspector

        well yes, AFAIK these are ppi spin-offs and Gabor's approach for padre.

        But if the OP is only talking about self-written classes and compares to java he might be happy about a robust attribute¹ based solution instead of relying on ppi's "guessing what the author meant".

        BTW: How do these modules handle AUTOLOAD?

        Cheers Rolf

        UPDATE: (1) Attribute::Handlers

Re: Compile-time/Auto-test method checking?
by CountZero (Bishop) on Jun 26, 2009 at 20:24 UTC
    Moose with its powerful meta and introspection methods and Class::MOP (on which Moose is based] go a long way in doing what you need, I think. However, they are all run-time and not compile-time tools.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

Re: Compile-time/Auto-test method checking?
by educated_foo (Vicar) on Jun 26, 2009 at 16:58 UTC
    If you use Emacs, check out find-grep-dired and dired-do-query-replace-regexp. It's not completely automatic, but still eases the pain.
Re: Compile-time/Auto-test method checking?
by Anonymous Monk on Jun 26, 2009 at 12:33 UTC
    not exactly a solution, just a comment..
    about a year ago I heard someone was trying to add perl support in netbeans, have you searched for this already ? perhaps they made it.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://774962]
Approved by Old_Gray_Bear
Front-paged by Old_Gray_Bear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (4)
As of 2024-04-18 05:29 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found