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

After being bitten one too many times, I'd like to more aggressively test my method parameters and return values. What is the best way to do this? Should I check defined() for each necessary parameter, or is that overkill since "use warnings" will tell me if I try to use it without being initialized? Do I check every single parameter using ref() to see if it's the type (scalar/hash/array) that I'm expecting? Do I do the same for every return value? I've looked for style guides about how to do this in perl, but I haven't come up with a satisfying answer. What do you all do? BTW, my program is large, OO, and spread across multiple files.

Replies are listed 'Best First'.
Re: Testing parameters and return values
by saintmike (Vicar) on Nov 04, 2005 at 18:24 UTC
Re: Testing parameters and return values
by friedo (Prior) on Nov 04, 2005 at 18:31 UTC
    I really like Params::Validate for this sort of thing. You can validate both named and positional parameters, you can make things mandatory or optional, you can check to see if it's the right kind of reference or object, check if an object provides a given interface, etc. You can even provide callback hooks to inspect the parameters yourself if P::V doesn't have a specific check that you need.
Re: Testing parameters and return values
by Tuppence (Pilgrim) on Nov 04, 2005 at 20:31 UTC

    The best way to do this is with a test suite. Testing your returns and input at run-time will cause performance degradation, and make it harder to modify the code by locking you down to how the code is written, versus what the code is supposed to do.

    Test::More is a pretty standard module for writing your tests with, and once you have started down that path Devel::Cover will be invaluable to find code paths you haven't tested yet.

    But what about scripts? If you refactor your scripts to be thin wrapppers around a module that you call, you can test the module and be confident the API's in your code that your script uses all work correctly and as you expect them to.

    Another large benefit to testing is it makes refactoring much easier, as you can rip out and rework large sections of code without worrying about if what the code is supposed to do is broken.

    Test driven development is a good subject to be familiar with, check it out. You might like it.

      If you're worried about performance of your live code you could use Carp::Assert. Assertions will compile out if you set no Carp::Assert; and thus have no performance impact on the live code. That way you can at least perform parameter/return checking in your integration and system tests. And if there are ever any weird problems with your live code you can turn the assertions on by commenting out a single line.


      Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. -- Brian W. Kernighan