NAME

Exception::Died - Convert simple die into real exception object

SYNOPSIS

# Can be loaded via Exception::Base pragma
use Exception::Base 'Exception::Died';

eval { open $f, "x", "bad_open_mode" };
Exception::Died->throw( message=>"cannot open" ) if $@;

eval { die "Bum!\n" };
if ($@) {
  my $e = Exception::Died->catch;
  $e->throw;
}

# Can replace die hook globally
use Exception::Died '%SIG' => 'die';
eval { die "Boom!\n" };
print ref $@;           # "Exception::Died"
print $@->eval_error;   # "Boom!"

# Can be used in local scope only
use Exception::Died;
{
    local $SIG{__DIE__} = \&Exception::Died::__DIE__;
    eval { die "Boom!"; }
    print ref $@;           # "Exception::Died"
    print $@->eval_error;   # "Boom!"
}
eval { die "Boom"; }
print ref $@;       # ""

DESCRIPTION

This class extends standard Exception::Base and converts eval's error into real exception object. The eval's error message is stored in eval_error attribute.

BASE CLASSES

IMPORTS

use Exception::Died '%SIG';
use Exception::Died '%SIG' => 'die';

Changes $SIG{__DIE__} hook to Exception::Died::__DIE__.

no Exception::Died '%SIG';

Undefines $SIG{__DIE__} hook.

CONSTANTS

ATTRS

Declaration of class attributes as reference to hash.

See Exception::Base for details.

ATTRIBUTES

This class provides new attributes. See Exception::Base for other descriptions.

eval_error (ro)

Contains the message from failed eval block. This attribute is automatically filled on object creation.

use Exception::Died '%SIG';
eval { die "string" };
print $@->eval_error;  # "string"
catch_can_rebless (rw)

Contains the flag for catch method which marks that this exception object should be reblessed. The flag is marked by internal __DIE__ hook.

eval_attribute (default: 'eval_error')

Meta-attribute contains the name of the attribute which is filled if error stack is empty. This attribute will contain value of $@ variable. This class overrides the default value from Exception::Base class.

stringify_attributes (default: ['message', 'eval_error'])

Meta-attribute contains the format of string representation of exception object. This class overrides the default value from Exception::Base class.

default_attribute (default: 'eval_error')

Meta-attribute contains the name of the default attribute. This class overrides the default value from Exception::Base class.

METHODS

CLASS->catch

This method overwrites the default catch method. It works as method from base class and has one exception in its behaviour.

If the popped value is an Exception::Died object and has an attribute catch_can_rebless set, this object is reblessed to class CLASS with its attributes unchanged. It is because original Exception::Base->catch method doesn't change exception class but it should be changed if Exception::Died handles $SIG{__DIE__} hook.

use Exception::Base
  'Exception::Fatal' => { isa => 'Exception::Died' },
  'Exception::Simple' => { isa => 'Exception::Died' };
use Exception::Died '%SIG' => 'die';

eval { die "Died\n"; };
my $e = Exception::Fatal->catch;
print ref $e;   # "Exception::Fatal"

eval { Exception::Simple->throw; };
my $e = Exception::Fatal->catch;
print ref $e;   # "Exception::Simple"

PRIVATE METHODS

_collect_system_data

Collect system data and fill the attributes of exception object. This method is called automatically if exception if throwed. This class overrides the method from Exception::Base class.

See Exception::Base.

PRIVATE FUNCTIONS

__DIE__

This is a hook function for $SIG{__DIE__}. This hook can be enabled with pragma:

use Exception::Died '%SIG';

or manually, i.e. for local scope:

local $SIG{__DIE__} = \&Exception::Died::__DIE__;

PERFORMANCE

The Exception::Died module can change $SIG{__DIE__} hook. It costs a speed for simple die operation. The failure scenario was benchmarked with default setting and with changed $SIG{__DIE__} hook.

-----------------------------------------------------------------------
| Module                              | Without %SIG  | With %SIG     |
-----------------------------------------------------------------------
| eval/die string                     |      237975/s |        3069/s |
-----------------------------------------------------------------------
| eval/die object                     |      124853/s |       90575/s |
-----------------------------------------------------------------------
| Exception::Base eval/if             |        8356/s |        7984/s |
-----------------------------------------------------------------------
| Exception::Base try/catch           |        9218/s |        8891/s |
-----------------------------------------------------------------------
| Exception::Base eval/if verbosity=1 |       14899/s |       14300/s |
-----------------------------------------------------------------------
| Exception::Base try/catch verbos.=1 |       18232/s |       16992/s |
-----------------------------------------------------------------------

It means that Exception::Died with die hook makes simple die 30 times slower. However it has no significant difference if the exception objects are used.

Note that Exception::Died will slow other exception implementations, like Class::Throwable and Exception::Class.

SEE ALSO

Exception::Base.

BUGS

If you find the bug, please report it.

AUTHOR

Piotr Roszatycki <dexter@debian.org>

LICENSE

Copyright (C) 2008 by Piotr Roszatycki <dexter@debian.org>.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

See http://www.perl.com/perl/misc/Artistic.html