The answer to your question is extremely complex, and I'm not even going to reveal it, because this is a bad solution to your real problem. What is the real problem? The problem is that you want the error inside a deeply nested subprogram call to cause a bubble on the stack. Exceptions are needed for this.
Here your code is rewritten for exception using croak .
package X; sub new { my $class = shift; my %args = @_; my $obj = bless \%args, $class; $obj->check_size; return $obj; } my $Max_Size = 1000; sub check_size { my $self = shift; if ($self->{size} > $Max_Size) { croak "size $self->{size} is too large, a maximum of $Max_Size is allowed"; } }
Then, when the user creates an invalid object ...
my $obj = X->new( size => 1234 );
check_size dies and throws an exception from the stack. If the user does nothing to stop him, they get the error message "size 1234 is too large, a maximum of 1000 is allowed at somefile line 234" . croak that the error message occurs at the point where new called, where the user made the error, and not somewhere deep inside X.pm.
Or they can write new () in eval BLOCK to catch the error.
my $obj = eval { X->new( size => 1234 ) } or do { ...something if the object isn't created... };
If you want to do something else when an error occurs, you can wrap croak in a method call.
sub error { my $self = shift; my $error = shift;
An exception from croak will cause the bubble to stack through error , check_size and new .
As daotoad points out, Try :: Tiny is a better exception handler than the direct eval BLOCK .
See If the Perl constructor returns an undef or "invalid" object? for more reasons why exceptions are a good idea.
Schwern
source share