Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Re: What Are The Rules For Subs And Modules When Fed Wrong Input

by flocto (Pilgrim)
on Jul 21, 2002 at 09:18 UTC ( [id://183800]=note: print w/replies, xml ) Need Help??


in reply to What Are The Rules For Subs And Modules When Fed Wrong Input

When writing objects I usually set an global variable $ERROR upon failure and return undef. $ERROR is then made available via an a method. This way I can have the script decide if it can live with that. An example code in the script could be the following, which is what I normally do.

my $mod = Module->new () or die Module->error (); my $foo = $mod->method () or warn $mod->error ();

Remains the question: Is more arguments than expected an error? Well, I usually ignore unneccessary arguments, but this too depends on the context. Another way I'm using (especially in constructor methods) is passing hashes and then check for existing keys. So in general I'd say it depends on the context, but I wouldn't let an object kill the entire program.

Regards,
-octo

Replies are listed 'Best First'.
Re: Re: What Are The Rules For Subs And Modules When Fed Wrong Input
by dimmesdale (Friar) on Jul 21, 2002 at 14:25 UTC
    I would say that the idea of an $ERROR variable is good in concept (similiar to the perl variable $!). However, if this is in a module then I think abstraction should be the key.

    This way I can have the script decide ...

    It's important, I agree, to let the script decide; however, the script shouldn't have to handle the code to decide.

    For example, there could be a warn method in your module (or error, etc.), that accepts a variable and then chooses the appropriate level to warn the calling program (or to die() itself).

    One benefit to this approach is that you can easily have the warn level in your program localized -- and contrary to handling it all yourself, changing what it is would be as simple as changing a parameter.

    This, of course, assumes that the module takes an OOP approach (which I'm biased towards myself).

Re: Re: What Are The Rules For Subs And Modules When Fed Wrong Input
by lofichurch (Beadle) on Jul 22, 2002 at 19:42 UTC

    I agree with the above error-handling technique. I hate to have a module die on me, ever. I also hate wrapping every call to a method in eval { } to assure that it doesn't die, and I want my logic to be able to know when there's been an error, not my user. The only points I would add would be to use an error method rather than variable, which gives the author / user some control (if they wish) over how the error is reported, and to make all methods return undef() on failure so that the person utilizing the module has a consistant activity for determining if an error occured. Any method that doesn't return data should return true (1), so that the user could say :

    if($object->method) { .. } else { my $error = $object->error(); }

    e.g.:

    sub foo { my($self,$arg) = @_; if( !defined($arg) ) { $self->error("[mymodule::foo] Required Argument, ARG, not supplied +.\n"); return(undef); } else { return(1); } }

    As a note for configurable error-handling methods, you could do something like this:

    sub error { my $self = shift; if( defined($_[0]) ) { $self->{'Error'} = $_[0]; if( $self->raise_error() ) { warn("$_[0]\n"); } if( $self->die_error() ) { die("$_[0]\n"); } } return($self->{'Error'}); }

    So there, you have a method that can be used both as an private method (for setting the error) and a public method (retrieving the error), with the ability for the user to configure how they get their errors back, as a scalar, a call to warn, or a call to die.

    Now, you'd also want to give them a method for configuring that activity, you could either do it via options when creating a new instance of the module, or you could give them method(s) like the following, which also handle the lookups for the error() method:

    sub raise_error { my $self = shift; $self->{'Raise'} = $_[0] if( defined($_[0]) ); return($self->{'Raise'}); }

    There, now you've got these methods that have both public and private interfaces, that effectivly handle whatever the user desires, but by default (you could set them to) require checks on return values and lookups with a method...


    !c

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://183800]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (5)
As of 2024-04-23 06:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found