in reply to validating function input

My answer applies only to OO stuff ( see above regarding when to use prototypes ).

For objects, the ->isa method is commonly used to check "Is an object of this class".

Of course, if you are taking arguments from outside the code you control, there's no way to know if ->isa will work, since isa'ing something that isn't an object will die.

BUT, calling UNIVERSAL::isa as a function directly CAN handle non-reference arguments, and correctly returns false. ( i.e. UNIVERSAL::isa( undef, 'Something' ) works, and correctly returns false )

I'm also a big fan of doing type checking ( where it doesn't get too large of course ) into the variable decleration. I'm also a fan of using return undef; to symbolise an error. Even in the cases where you have true/false responses, you can use true/false/undef ( 1/''/undef )

SO, for most of my OO stuff, and there's a lot of it, I use something like the following.

package Foo; use strict; sub bar { my $File = UNIVERSAL::isa( $_[0], 'IO::File' ) ? shift : return un +def; # Do something to file } 1;
Of course, all those UNIVERSAL::isa's get virtually RSI like to type, so for convenience, I use the following.
package Foo; use strict; use UNIVERSAL 'isa'; sub Foo { my $File = isa( $_[0], 'IO::File' ) ? shift : return undef; # Do something to the file } 1;
I find this highly useful, especially for reasonably large quantities of arguments. Because you don't shift first and check later, you never forget to check.

Replies are listed 'Best First'.
Re: Re: validating function input
by adamk (Chaplain) on May 23, 2003 at 00:34 UTC
    I should mention there is a variety of different uses for this as well.

    The most common are:

    sub foo { my $self = shift; # Is there a variable at all ( even undef ) my $anything = @_ ? shift : return undef; # Is there a defined argument my $def = defined $_[0] ? shift : return undef; # Is there a true argument my $true = $_[0] ? shift : return undef; # Is there an argument which conforms to a regex? my $re_ok = $_[0] =~ /^\w+$/ ? shift : return undef; # If the argument one of a limited number of values my $option = $_[0] =~ /^(?:this|that|foo|bar)$/ ? shift : return u +ndef; # Is it a reference my $ref = ref $_[0] ? shift : return undef;
    You get my point... it can be extended to cover most of the basics pretty well, and it probably much faster than calling to another subroutine.