nix-archive-1(type directoryentry(namelibnode(type directoryentry(nameperl5node(type directoryentry(name site_perlnode(type directoryentry(name5.36.0node(type directoryentry(name Exceptionnode(type directoryentry(nameClassnode(type directoryentry(nameBase.pmnode(typeregularcontents?package Exception::Class::Base; use strict; use warnings; our $VERSION = '1.44'; use Class::Data::Inheritable 0.02; use Devel::StackTrace 2.00; use Scalar::Util qw( blessed ); use base qw(Class::Data::Inheritable); BEGIN { __PACKAGE__->mk_classdata('Trace'); __PACKAGE__->mk_classdata('UnsafeRefCapture'); __PACKAGE__->mk_classdata('NoContextInfo'); __PACKAGE__->NoContextInfo(0); __PACKAGE__->mk_classdata('RespectOverload'); __PACKAGE__->RespectOverload(0); __PACKAGE__->mk_classdata('MaxArgLength'); __PACKAGE__->MaxArgLength(0); sub NoRefs { my $self = shift; if (@_) { my $val = shift; return $self->UnsafeRefCapture( !$val ); } else { return $self->UnsafeRefCapture; } } sub Fields { () } } use overload # an exception is always true bool => sub {1}, '""' => 'as_string', fallback => 1; # Create accessor routines BEGIN { my @fields = qw( message pid uid euid gid egid time trace ); foreach my $f (@fields) { my $sub = sub { my $s = shift; return $s->{$f}; }; ## no critic (TestingAndDebugging::ProhibitNoStrict) no strict 'refs'; *{$f} = $sub; } *error = \&message; my %trace_fields = ( package => 'package', file => 'filename', line => 'line', ); while ( my ( $f, $m ) = each %trace_fields ) { my $sub = sub { my $s = shift; return $s->{$f} if exists $s->{$f}; my $frame = $s->trace->frame(0); return $s->{$f} = $frame ? $frame->$m : undef; }; ## no critic (TestingAndDebugging::ProhibitNoStrict) no strict 'refs'; *{$f} = $sub; } } sub Classes { Exception::Class::Classes() } sub throw { my $proto = shift; $proto->rethrow if ref $proto; die $proto->new(@_); } sub rethrow { my $self = shift; die $self; } sub new { my $proto = shift; my $class = ref $proto || $proto; my $self = bless {}, $class; $self->_initialize(@_); return $self; } sub _initialize { my $self = shift; my %p = @_ == 1 ? ( error => $_[0] ) : @_; $self->{message} = $p{message} || $p{error} || q{}; $self->{show_trace} = $p{show_trace} if exists $p{show_trace}; if ( $self->NoContextInfo ) { $self->{show_trace} = 0; $self->{package} = $self->{file} = $self->{line} = undef; } else { # CORE::time is important to fix an error with some versions of # Perl $self->{time} = CORE::time(); $self->{pid} = $$; $self->{uid} = $<; $self->{euid} = $>; $self->{gid} = $(; $self->{egid} = $); my @ignore_class = (__PACKAGE__); my @ignore_package = 'Exception::Class'; if ( my $i = delete $p{ignore_class} ) { push @ignore_class, ( ref($i) eq 'ARRAY' ? @$i : $i ); } if ( my $i = delete $p{ignore_package} ) { push @ignore_package, ( ref($i) eq 'ARRAY' ? @$i : $i ); } $self->{trace} = Devel::StackTrace->new( ignore_class => \@ignore_class, ignore_package => \@ignore_package, unsafe_ref_capture => $self->UnsafeRefCapture, respect_overload => $self->RespectOverload, max_arg_length => $self->MaxArgLength, map { $p{$_} ? ( $_ => delete $p{$_} ) : () } qw( frame_filter filter_frames_early skip_frames ), ); } my %fields = map { $_ => 1 } $self->Fields; while ( my ( $key, $value ) = each %p ) { next if $key =~ /^(?:error|message|show_trace)$/; if ( $fields{$key} ) { $self->{$key} = $value; } else { Exception::Class::Base->throw( error => "unknown field $key passed to constructor for class " . ref $self ); } } } sub context_hash { my $self = shift; return { time => $self->{time}, pid => $self->{pid}, uid => $self->{uid}, euid => $self->{euid}, gid => $self->{gid}, egid => $self->{egid}, }; } sub field_hash { my $self = shift; my $hash = {}; for my $field ( $self->Fields ) { $hash->{$field} = $self->$field; } return $hash; } sub description { return 'Generic exception'; } sub show_trace { my $self = shift; return 0 unless $self->{trace}; if (@_) { $self->{show_trace} = shift; } return exists $self->{show_trace} ? $self->{show_trace} : $self->Trace; } sub as_string { my $self = shift; my $str = $self->full_message; unless ( defined $str && length $str ) { my $desc = $self->description; $str = defined $desc && length $desc ? "[$desc]" : '[Generic exception]'; } $str .= "\n\n" . $self->trace->as_string if $self->show_trace; return $str; } sub full_message { $_[0]->message } # # The %seen bit protects against circular inheritance. # ## no critic (BuiltinFunctions::ProhibitStringyEval, ErrorHandling::RequireCheckingReturnValueOfEval) eval <<'EOF' if $] == 5.006; sub isa { my ( $inheritor, $base ) = @_; $inheritor = ref($inheritor) if ref($inheritor); my %seen; no strict 'refs'; my @parents = ( $inheritor, @{"$inheritor\::ISA"} ); while ( my $class = shift @parents ) { return 1 if $class eq $base; push @parents, grep { !$seen{$_}++ } @{"$class\::ISA"}; } return 0; } EOF sub caught { my $class = shift; my $e = $@; return unless defined $e && blessed($e) && $e->isa($class); return $e; } 1; # ABSTRACT: A base class for exception objects __END__ =pod =encoding UTF-8 =head1 NAME Exception::Class::Base - A base class for exception objects =head1 VERSION version 1.44 =head1 SYNOPSIS use Exception::Class 'MyException'; eval { MyException->throw( error => 'I feel funny.' ) }; print $@->error; =head1 DESCRIPTION This class is the base class for all exceptions created by L. It provides a number of methods for getting information about the exception. =for Pod::Coverage Classes caught NoRefs =head1 METHODS =head2 MyException->Trace($boolean) Each C subclass can be set individually to include a stacktrace when the C method is called. The default is to not include a stacktrace. Calling this method with a value changes this behavior. It always returns the current value (after any change is applied). This value is inherited by any subclasses. However, if this value is set for a subclass, it will thereafter be independent of the value in C. Do not call this on the C class directly or you'll change it for all exception classes that use L, including ones created in modules you don't control. This is a class method, not an object method. =head2 MyException->UnsafeRefCapture($boolean) When a C object is created, it walks through the stack and stores the arguments which were passed to each subroutine on the stack. If any of these arguments are references, then that means that the C ends up increasing the ref count of these references, delaying their destruction. Since C uses C internally, this method provides a way to tell C not to store these references. Instead, C replaces references with their stringified representation. This method defaults to false. As with C, it is inherited by subclasses but setting it in a subclass makes it independent thereafter. Do not call this on the C class directly or you'll change it for all exception classes that use L, including ones created in modules you don't control. =head2 MyException->RespectOverload($boolean) When a C object stringifies, by default it ignores stringification overloading on any objects being dealt with. Since C uses C internally, this method provides a way to tell C to respect overloading. This method defaults to false. As with C, it is inherited by subclasses but setting it in a subclass makes it independent thereafter. Do not call this on the C class directly or you'll change it for all exception classes that use L, including ones created in modules you don't control. =head2 MyException->MaxArgLength($boolean) When a C object stringifies, by default it displays the full argument for each function. This parameter can be used to limit the maximum length of each argument. Since C uses C internally, this method provides a way to tell C to limit the length of arguments. This method defaults to 0. As with C, it is inherited by subclasses but setting it in a subclass makes it independent thereafter. Do not call this on the C class directly or you'll change it for all exception classes that use L, including ones created in modules you don't control. =head2 MyException->Fields This method returns the extra fields defined for the given class, as a list. Do not call this on the C class directly or you'll change it for all exception classes that use L, including ones created in modules you don't control. =head2 MyException->throw( $message ) =head2 MyException->throw( message => $message ) =head2 MyException->throw( error => $error ) This method creates a new object with the given error message. If no error message is given, this will be an empty string. It then dies with this object as its argument. This method also takes a C parameter which indicates whether or not the particular exception object being created should show a stacktrace when its C method is called. This overrides the value of C for this class if it is given. The frames included in the trace can be controlled by the C and C parameters. These are passed directly to Devel::Stacktrace's constructor. See C for more details. This class B passes C<__PACKAGE__> for C and C<'Exception::Class'> for C, in addition to any arguments you provide. If only a single value is given to the constructor it is assumed to be the message parameter. Additional keys corresponding to the fields defined for the particular exception subclass will also be accepted. =head2 MyException->new(...) This method takes the same parameters as C, but instead of dying simply returns a new exception object. This method is always called when constructing a new exception object via the C method. =head2 MyException->description Returns the description for the given C subclass. The C class's description is "Generic exception" (this may change in the future). This is also an object method. =head2 $exception->rethrow Simply dies with the object as its sole argument. It's just syntactic sugar. This does not change any of the object's attribute values. However, it will cause C to report the die as coming from within the C class rather than where rethrow was called. Of course, you always have access to the original stacktrace for the exception object. =head2 $exception->message =head2 $exception->error Returns the error/message associated with the exception. =head2 $exception->pid Returns the pid at the time the exception was thrown. =head2 $exception->uid Returns the real user id at the time the exception was thrown. =head2 $exception->gid Returns the real group id at the time the exception was thrown. =head2 $exception->euid Returns the effective user id at the time the exception was thrown. =head2 $exception->egid Returns the effective group id at the time the exception was thrown. =head2 $exception->time Returns the time in seconds since the epoch at the time the exception was thrown. =head2 $exception->package Returns the package from which the exception was thrown. =head2 $exception->file Returns the file within which the exception was thrown. =head2 $exception->line Returns the line where the exception was thrown. =head2 $exception->context_hash Returns a hash reference with the following keys: =over 4 =item * time =item * pid =item * uid =item * euid =item * gid =item * egid =back =head2 $exception->field_hash Returns a hash reference where the keys are any fields defined for the exception class and the values are the values associated with the field in the given object. =head2 $exception->trace Returns the trace object associated with the object. =head2 $exception->show_trace($boolean) This method can be used to set whether or not a stack trace is included when the as_string method is called or the object is stringified. =head2 $exception->as_string Returns a string form of the error message (something like what you'd expect from die). If the class or object is set to show traces then then the full trace is also included. The result looks like C. =head2 $exception->full_message Called by the C method to get the message. By default, this is the same as calling the C method, but may be overridden by a subclass. See below for details. =head1 LIGHTWEIGHT EXCEPTIONS A lightweight exception is one which records no information about its context when it is created. This can be achieved by setting C<< $class->NoContextInfo >> to a true value. You can make this the default for a class of exceptions by setting it after creating the class: use Exception::Class ( 'LightWeight', 'HeavyWeight', ); LightWeight->NoContextInfo(1); A lightweight exception does have a stack trace object, nor does it record the time, pid, uid, euid, gid, or egid. It only has a message. =head1 OVERLOADING C objects are overloaded so that stringification produces a normal error message. This just calls the C<< $exception->as_string >> method described above. This means that you can just C after an C and not worry about whether or not its an actual object. It also means an application or module could do this: $SIG{__DIE__} = sub { Exception::Class::Base->throw( error => join '', @_ ); }; and this would probably not break anything (unless someone was expecting a different type of exception object from C). =head1 OVERRIDING THE as_string METHOD By default, the C method simply returns the value C or C param plus a stack trace, if the class's C method returns a true value or C was set when creating the exception. However, once you add new fields to a subclass, you may want to include those fields in the stringified error. Inside the C method, the message (non-stack trace) portion of the error is generated by calling the C method. This can be easily overridden. For example: sub full_message { my $self = shift; my $msg = $self->message; $msg .= " and foo was " . $self->foo; return $msg; } =head1 SUPPORT Bugs may be submitted at L. I am also usually active on IRC as 'autarch' on C. =head1 SOURCE The source code repository for Exception-Class can be found at L. =head1 AUTHOR Dave Rolsky =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2017 by Dave Rolsky. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. The full text of the license can be found in the F file included with this distribution. =cut ))))entry(nameClass.pmnode(typeregularcontentsBpackage Exception::Class; use 5.008001; use strict; use warnings; our $VERSION = '1.44'; use Exception::Class::Base; use Scalar::Util qw( blessed reftype ); our $BASE_EXC_CLASS; BEGIN { $BASE_EXC_CLASS ||= 'Exception::Class::Base'; } our %CLASSES; sub import { my $class = shift; ## no critic (Variables::ProhibitPackageVars) local $Exception::Class::Caller = caller(); my %c; my %needs_parent; while ( my $subclass = shift ) { my $def = ref $_[0] ? shift : {}; $def->{isa} = $def->{isa} ? ( ref $def->{isa} ? $def->{isa} : [ $def->{isa} ] ) : []; $c{$subclass} = $def; } # We need to sort by length because if we check for keys in the # Foo::Bar:: stash, this creates a "Bar::" key in the Foo:: stash! MAKE_CLASSES: foreach my $subclass ( sort { length $a <=> length $b } keys %c ) { my $def = $c{$subclass}; # We already made this one. next if $CLASSES{$subclass}; { ## no critic (TestingAndDebugging::ProhibitNoStrict) no strict 'refs'; foreach my $parent ( @{ $def->{isa} } ) { unless ( keys %{"$parent\::"} ) { $needs_parent{$subclass} = { parents => $def->{isa}, def => $def }; next MAKE_CLASSES; } } } $class->_make_subclass( subclass => $subclass, def => $def || {}, ); } foreach my $subclass ( keys %needs_parent ) { # This will be used to spot circular references. my %seen; $class->_make_parents( \%needs_parent, $subclass, \%seen ); } } sub _make_parents { my $class = shift; my $needs = shift; my $subclass = shift; my $seen = shift; my $child = shift; # Just for error messages. ## no critic (TestingAndDebugging::ProhibitNoStrict, TestingAndDebugging::ProhibitProlongedStrictureOverride) no strict 'refs'; # What if someone makes a typo in specifying their 'isa' param? # This should catch it. Either it's been made because it didn't # have missing parents OR it's in our hash as needing a parent. # If neither of these is true then the _only_ place it is # mentioned is in the 'isa' param for some other class, which is # not a good enough reason to make a new class. die "Class $subclass appears to be a typo as it is only specified in the 'isa' param for $child\n" unless exists $needs->{$subclass} || $CLASSES{$subclass} || keys %{"$subclass\::"}; foreach my $c ( @{ $needs->{$subclass}{parents} } ) { # It's been made next if $CLASSES{$c} || keys %{"$c\::"}; die "There appears to be some circularity involving $subclass\n" if $seen->{$subclass}; $seen->{$subclass} = 1; $class->_make_parents( $needs, $c, $seen, $subclass ); } return if $CLASSES{$subclass} || keys %{"$subclass\::"}; $class->_make_subclass( subclass => $subclass, def => $needs->{$subclass}{def} ); } sub _make_subclass { my $class = shift; my %p = @_; my $subclass = $p{subclass}; my $def = $p{def}; my $isa; if ( $def->{isa} ) { $isa = ref $def->{isa} ? join q{ }, @{ $def->{isa} } : $def->{isa}; } $isa ||= $BASE_EXC_CLASS; my $version_name = 'VERSION'; my $code = <<"EOPERL"; package $subclass; use base qw($isa); our \$$version_name = '1.1'; 1; EOPERL if ( $def->{description} ) { ( my $desc = $def->{description} ) =~ s/([\\\'])/\\$1/g; $code .= <<"EOPERL"; sub description { return '$desc'; } EOPERL } my @fields; if ( my $fields = $def->{fields} ) { @fields = ref $fields && reftype $fields eq 'ARRAY' ? @$fields : $fields; $code .= 'sub Fields { return ($_[0]->SUPER::Fields, ' . join( ', ', map {"'$_'"} @fields ) . ") }\n\n"; foreach my $field (@fields) { $code .= sprintf( "sub %s { \$_[0]->{%s} }\n", $field, $field ); } } if ( my $alias = $def->{alias} ) { ## no critic (Variables::ProhibitPackageVars) die 'Cannot make alias without caller' unless defined $Exception::Class::Caller; ## no critic (TestingAndDebugging::ProhibitNoStrict) no strict 'refs'; *{"$Exception::Class::Caller\::$alias"} = sub { $subclass->throw(@_) }; } if ( my $defaults = $def->{defaults} ) { $code .= "sub _defaults { return shift->SUPER::_defaults, our \%_DEFAULTS }\n"; ## no critic (TestingAndDebugging::ProhibitNoStrict) no strict 'refs'; *{"$subclass\::_DEFAULTS"} = {%$defaults}; } ## no critic (BuiltinFunctions::ProhibitStringyEval, ErrorHandling::RequireCheckingReturnValueOfEval) eval $code; die $@ if $@; ( my $filename = "$subclass.pm" ) =~ s{::}{/}g; $INC{$filename} = __FILE__; $CLASSES{$subclass} = 1; } sub caught { my $e = $@; return $e unless $_[1]; return unless blessed($e) && $e->isa( $_[1] ); return $e; } sub Classes { sort keys %Exception::Class::CLASSES } 1; # ABSTRACT: A module that allows you to declare real exception classes in Perl __END__ =pod =encoding UTF-8 =head1 NAME Exception::Class - A module that allows you to declare real exception classes in Perl =head1 VERSION version 1.44 =head1 SYNOPSIS use Exception::Class ( 'MyException', 'AnotherException' => { isa => 'MyException' }, 'YetAnotherException' => { isa => 'AnotherException', description => 'These exceptions are related to IPC' }, 'ExceptionWithFields' => { isa => 'YetAnotherException', fields => [ 'grandiosity', 'quixotic' ], alias => 'throw_fields', }, ); use Scalar::Util qw( blessed ); use Try::Tiny; try { MyException->throw( error => 'I feel funny.' ); } catch { die $_ unless blessed $_ && $_->can('rethrow'); if ( $_->isa('Exception::Class') ) { warn $_->error, "\n", $_->trace->as_string, "\n"; warn join ' ', $_->euid, $_->egid, $_->uid, $_->gid, $_->pid, $_->time; exit; } elsif ( $_->isa('ExceptionWithFields') ) { if ( $_->quixotic ) { handle_quixotic_exception(); } else { handle_non_quixotic_exception(); } } else { $_->rethrow; } }; # without Try::Tiny eval { ... }; if ( my $e = Exception::Class->caught ) { ... } # use an alias - without parens subroutine name is checked at # compile time throw_fields error => "No strawberry", grandiosity => "quite a bit"; =head1 DESCRIPTION B: If you are writing modern Perl code with L or L I highly recommend using L instead of this module. B: Whether or not you use L, you should use L. Exception::Class allows you to declare exception hierarchies in your modules in a "Java-esque" manner. It features a simple interface allowing programmers to 'declare' exception classes at compile time. It also has a base exception class, L, that can be easily extended. It is designed to make structured exception handling simpler and better by encouraging people to use hierarchies of exceptions in their applications, as opposed to a single catch-all exception class. This module does not implement any try/catch syntax. Please see the "OTHER EXCEPTION MODULES (try/catch syntax)" section for more information on how to get this syntax. You will also want to look at the documentation for L, which is the default base class for all exception objects created by this module. =for Pod::Coverage Classes caught =head1 DECLARING EXCEPTION CLASSES Importing C allows you to automagically create L subclasses. You can also create subclasses via the traditional means of defining your own subclass with C<@ISA>. These two methods may be easily combined, so that you could subclass an exception class defined via the automagic import, if you desired this. The syntax for the magic declarations is as follows: 'MANDATORY CLASS NAME' => \%optional_hashref The hashref may contain the following options: =over 4 =item * isa This is the class's parent class. If this isn't provided then the class name in C<$Exception::Class::BASE_EXC_CLASS> is assumed to be the parent (see below). This parameter lets you create arbitrarily deep class hierarchies. This can be any other L subclass in your declaration I a subclass loaded from a module. To change the default exception class you will need to change the value of C<$Exception::Class::BASE_EXC_CLASS> I calling C. To do this simply do something like this: BEGIN { $Exception::Class::BASE_EXC_CLASS = 'SomeExceptionClass'; } If anyone can come up with a more elegant way to do this please let me know. CAVEAT: If you want to automagically subclass an L subclass loaded from a file, then you I compile the class (via use or require or some other magic) I you import C or you'll get a compile time error. =item * fields This allows you to define additional attributes for your exception class. Any field you define can be passed to the C or C methods as additional parameters for the constructor. In addition, your exception object will have an accessor method for the fields you define. This parameter can be either a scalar (for a single field) or an array reference if you need to define multiple fields. Fields will be inherited by subclasses. =item * alias Specifying an alias causes this class to create a subroutine of the specified name in the I namespace. Calling this subroutine is equivalent to calling C<< ->throw(@_) >> for the given exception class. Besides convenience, using aliases also allows for additional compile time checking. If the alias is called I, as in C, then Perl checks for the existence of the C subroutine at compile time. If instead you do C<< ExceptionWithFields->throw(...) >>, then Perl checks the class name at runtime, meaning that typos may sneak through. =item * description Each exception class has a description method that returns a fixed string. This should describe the exception I (as opposed to any particular exception object). This may be useful for debugging if you start catching exceptions you weren't expecting (particularly if someone forgot to document them) and you don't understand the error messages. =back The C magic attempts to detect circular class hierarchies and will die if it finds one. It also detects missing links in a chain, for example if you declare Bar to be a subclass of Foo and never declare Foo. =head1 L If you are interested in adding try/catch/finally syntactic sugar to your code then I recommend you check out L. This is a great module that helps you ignore some of the weirdness with C and C<$@>. Here's an example of how the two modules work together: use Exception::Class ( 'My::Exception' ); use Scalar::Util qw( blessed ); use Try::Tiny; try { might_throw(); } catch { if ( blessed $_ && $_->isa('My::Exception') ) { handle_it(); } else { die $_; } }; Note that you B use C<< Exception::Class->caught >> with L. =head1 Catching Exceptions Without L C provides some syntactic sugar for catching exceptions in a safe manner: eval {...}; if ( my $e = Exception::Class->caught('My::Error') ) { cleanup(); do_something_with_exception($e); } The C method takes a class name and returns an exception object if the last thrown exception is of the given class, or a subclass of that class. If it is not given any arguments, it simply returns C<$@>. You should B make a copy of the exception object, rather than using C<$@> directly. This is necessary because if your C function uses C, or calls something which uses it, then C<$@> is overwritten. Copying the exception preserves it for the call to C. Exception objects also provide a caught method so you can write: if ( my $e = My::Error->caught ) { cleanup(); do_something_with_exception($e); } =head2 Uncatchable Exceptions Internally, the C method will call C on the exception object. You could make an exception "uncatchable" by overriding C in that class like this: package Exception::Uncatchable; sub isa { shift->rethrow } Of course, this only works if you always call C<< Exception::Class->caught >> after an C. =head1 USAGE RECOMMENDATION If you're creating a complex system that throws lots of different types of exceptions, consider putting all the exception declarations in one place. For an app called Foo you might make a C module and use that in all your code. This module could just contain the code to make C do its automagic class creation. Doing this allows you to more easily see what exceptions you have, and makes it easier to keep track of them. This might look something like this: package Foo::Bar::Exceptions; use Exception::Class ( Foo::Bar::Exception::Senses => { description => 'sense-related exception' }, Foo::Bar::Exception::Smell => { isa => 'Foo::Bar::Exception::Senses', fields => 'odor', description => 'stinky!' }, Foo::Bar::Exception::Taste => { isa => 'Foo::Bar::Exception::Senses', fields => [ 'taste', 'bitterness' ], description => 'like, gag me with a spoon!' }, ... ); You may want to create a real module to subclass L as well, particularly if you want your exceptions to have more methods. =head2 Subclassing Exception::Class::Base As part of your usage of C, you may want to create your own base exception class which subclasses L. You should feel free to subclass any of the methods documented above. For example, you may want to subclass C to add additional information to your exception objects. =head1 Exception::Class FUNCTIONS The C method offers one function, C, which is not exported. This method returns a list of the classes that have been created by calling the C C method. Note that this is I the subclasses that have been created, so it may include subclasses created by things like CPAN modules, etc. Also note that if you simply define a subclass via the normal Perl method of setting C<@ISA> or C, then your subclass will not be included. =head1 SUPPORT Bugs may be submitted at L. I am also usually active on IRC as 'autarch' on C. =head1 SOURCE The source code repository for Exception-Class can be found at L. =head1 DONATIONS If you'd like to thank me for the work I've done on this module, please consider making a "donation" to me via PayPal. I spend a lot of free time creating free software, and would appreciate any support you'd care to offer. Please note that B in order for me to continue working on this particular software. I will continue to do so, inasmuch as I have in the past, for as long as it interests me. Similarly, a donation made in this way will probably not make me work on this software much more, unless I get so many donations that I can consider working on free software full time (let's all have a chuckle at that together). To donate, log into PayPal and send money to autarch@urth.org, or use the button at L. =head1 AUTHOR Dave Rolsky =head1 CONTRIBUTORS =for stopwords Alexander Batyrshin Leon Timmermans Ricardo Signes =over 4 =item * Alexander Batyrshin <0x62ash@gmail.com> =item * Leon Timmermans =item * Ricardo Signes =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2017 by Dave Rolsky. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. The full text of the license can be found in the F file included with this distribution. =cut ))))entry(nameaarch64-linux-thread-multinode(type directoryentry(nameautonode(type directoryentry(name Exceptionnode(type directoryentry(nameClassnode(type directoryentry(name .packlistnode(typeregularcontents/gnu/store/02v8nxg6xdmncrpa3gwxylk47jshbxca-perl-exception-class-1.44/lib/perl5/site_perl/5.36.0/Exception/Class.pm /gnu/store/02v8nxg6xdmncrpa3gwxylk47jshbxca-perl-exception-class-1.44/lib/perl5/site_perl/5.36.0/Exception/Class/Base.pm /gnu/store/02v8nxg6xdmncrpa3gwxylk47jshbxca-perl-exception-class-1.44/share/man/man3/Exception::Class.3 /gnu/store/02v8nxg6xdmncrpa3gwxylk47jshbxca-perl-exception-class-1.44/share/man/man3/Exception::Class::Base.3 ))))))))))))))))))entry(namesharenode(type directoryentry(namedocnode(type directoryentry(nameperl-exception-class-1.44node(type directoryentry(nameLICENSEnode(typeregularcontentsGThis software is copyright (c) 2017 by Dave Rolsky. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. Terms of the Perl programming language system itself a) the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version, or b) the "Artistic License" --- The GNU General Public License, Version 1, February 1989 --- This software is Copyright (c) 2017 by Dave Rolsky. This is free software, licensed under: The GNU General Public License, Version 1, February 1989 GNU GENERAL PUBLIC LICENSE Version 1, February 1989 Copyright (C) 1989 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The license agreements of most software companies try to keep users at the mercy of those companies. By contrast, our General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. The General Public License applies to the Free Software Foundation's software and to any other program whose authors commit to using it. You can use it for your programs, too. When we speak of free software, we are referring to freedom, not price. Specifically, the General Public License is designed to make sure that you have the freedom to give away or sell copies of free software, that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of a such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must tell them their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any work containing the Program or a portion of it, either verbatim or with modifications. Each licensee is addressed as "you". 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this General Public License and to the absence of any warranty; and give any other recipients of the Program a copy of this General Public License along with the Program. You may charge a fee for the physical act of transferring a copy. 2. You may modify your copy or copies of the Program or any portion of it, and copy and distribute such modifications under the terms of Paragraph 1 above, provided that you also do the following: a) cause the modified files to carry prominent notices stating that you changed the files and the date of any change; and b) cause the whole of any work that you distribute or publish, that in whole or in part contains the Program or any part thereof, either with or without modifications, to be licensed at no charge to all third parties under the terms of this General Public License (except that you may choose to grant warranty protection to some or all third parties, at your option). c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the simplest and most usual way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this General Public License. d) You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. Mere aggregation of another independent work with the Program (or its derivative) on a volume of a storage or distribution medium does not bring the other work under the scope of these terms. 3. You may copy and distribute the Program (or a portion or derivative of it, under Paragraph 2) in object code or executable form under the terms of Paragraphs 1 and 2 above provided that you also do one of the following: a) accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Paragraphs 1 and 2 above; or, b) accompany it with a written offer, valid for at least three years, to give any third party free (except for a nominal charge for the cost of distribution) a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Paragraphs 1 and 2 above; or, c) accompany it with the information you received as to where the corresponding source code may be obtained. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form alone.) Source code for a work means the preferred form of the work for making modifications to it. For an executable file, complete source code means all the source code for all modules it contains; but, as a special exception, it need not include source code for modules which are standard libraries that accompany the operating system on which the executable file runs, or for standard header files or definitions files that accompany that operating system. 4. You may not copy, modify, sublicense, distribute or transfer the Program except as expressly provided under this General Public License. Any attempt otherwise to copy, modify, sublicense, distribute or transfer the Program is void, and will automatically terminate your rights to use the Program under this License. However, parties who have received copies, or rights to use copies, from you under this General Public License will not have their licenses terminated so long as such parties remain in full compliance. 5. By copying, distributing or modifying the Program (or any work based on the Program) you indicate your acceptance of this license to do so, and all its terms and conditions. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. 7. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of the license which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the license, you may choose any version ever published by the Free Software Foundation. 8. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to humanity, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19xx name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (a program to direct compilers to make passes at assemblers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice That's all there is to it! --- The Artistic License 1.0 --- This software is Copyright (c) 2017 by Dave Rolsky. This is free software, licensed under: The Artistic License 1.0 The Artistic License Preamble The intent of this document is to state the conditions under which a Package may be copied, such that the Copyright Holder maintains some semblance of artistic control over the development of the package, while giving the users of the package the right to use and distribute the Package in a more-or-less customary fashion, plus the right to make reasonable modifications. Definitions: - "Package" refers to the collection of files distributed by the Copyright Holder, and derivatives of that collection of files created through textual modification. - "Standard Version" refers to such a Package if it has not been modified, or has been modified in accordance with the wishes of the Copyright Holder. - "Copyright Holder" is whoever is named in the copyright or copyrights for the package. - "You" is you, if you're thinking about copying or distributing this Package. - "Reasonable copying fee" is whatever you can justify on the basis of media cost, duplication charges, time of people involved, and so on. (You will not be required to justify it to the Copyright Holder, but only to the computing community at large as a market that must bear the fee.) - "Freely Available" means that no fee is charged for the item itself, though there may be fees involved in handling the item. It also means that recipients of the item may redistribute it under the same conditions they received it. 1. You may make and give away verbatim copies of the source form of the Standard Version of this Package without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers. 2. You may apply bug fixes, portability fixes and other modifications derived from the Public Domain or from the Copyright Holder. A Package modified in such a way shall still be considered the Standard Version. 3. You may otherwise modify your copy of this Package in any way, provided that you insert a prominent notice in each changed file stating how and when you changed that file, and provided that you do at least ONE of the following: a) place your modifications in the Public Domain or otherwise make them Freely Available, such as by posting said modifications to Usenet or an equivalent medium, or placing the modifications on a major archive site such as ftp.uu.net, or by allowing the Copyright Holder to include your modifications in the Standard Version of the Package. b) use the modified Package only within your corporation or organization. c) rename any non-standard executables so the names do not conflict with standard executables, which must also be provided, and provide a separate manual page for each non-standard executable that clearly documents how it differs from the Standard Version. d) make other distribution arrangements with the Copyright Holder. 4. You may distribute the programs of this Package in object code or executable form, provided that you do at least ONE of the following: a) distribute a Standard Version of the executables and library files, together with instructions (in the manual page or equivalent) on where to get the Standard Version. b) accompany the distribution with the machine-readable source of the Package with your modifications. c) accompany any non-standard executables with their corresponding Standard Version executables, giving the non-standard executables non-standard names, and clearly documenting the differences in manual pages (or equivalent), together with instructions on where to get the Standard Version. d) make other distribution arrangements with the Copyright Holder. 5. You may charge a reasonable copying fee for any distribution of this Package. You may charge any fee you choose for support of this Package. You may not charge a fee for this Package itself. However, you may distribute this Package in aggregate with other (possibly commercial) programs as part of a larger (possibly commercial) software distribution provided that you do not advertise this Package as a product of your own. 6. The scripts and library files supplied as input to or produced as output from the programs of this Package do not automatically fall under the copyright of this Package, but belong to whomever generated them, and may be sold commercially, and may be aggregated with this Package. 7. C or perl subroutines supplied by you and linked into this Package shall not be considered part of this Package. 8. The name of the Copyright Holder may not be used to endorse or promote products derived from this software without specific prior written permission. 9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. The End ))))))entry(namemannode(type directoryentry(nameman3node(type directoryentry(nameException::Class.3.zstnode(typeregularcontents(/d*;Z0ȪWjmf1d@~,\^o[7Xx RrSK F@L$d҄ʏC0W+]Z7ܖ}(ߖ:J+#3rq`PZD >Eb I h{Nz~{c+ IZiI̠(Wm(ntȕكV:s5\16aml <@`CDcHR" Q723gaI@7-m T( $ >אe=ٜ Z&rr4wz\9JϚV$$\;Tb3W.5aUCN5×sIȯf6[[s ?>P1*7{2jFlr |+zc?3~rZiB=! Jͣrr=CZNbH.' er衘2]ejL>\eDD4&]rWWn)ůH& u[)b2RFAm)~V7fuP&3FAsh1 OY1lanK)r= %cE$Eaam4 SXyJmuez97m UkDeQt6D66a;v3~8nð`u)=z7$0J!@17rQ;Zvp3Rߚ55պ2ɐ_c2Q*@y{Wv:8f؞q /,Lr^]boZؐ"_SMBJf$l )s"FX&P s:j|>eIIH`<\Vy}rhϹ678 G 0~wYKk@D(ःE@8@@#FAL&RGj%" xFl~32 I%sx[Qk?NR)|B vb\lwP-cfh*z Se;d~sP"#mnҩJ8ܻjF̵^L-@\eZD,9^EȨO[H\EZDAGk#3 =a٣)bĵAsvE &rTiJFoBWQϙήڅ^CypޤYm''tJ&Jȹ<'4,/j᫞s5fs,]/{9_4wCZپoBxK[yjRifMR5PdTGHm;PaBT~mcȲ"UL1I 1s@0 0L413FCR@6E?6_LxK ɖ|%h SaMeǜ<ݻ5&ߪ=BmSo 5*\og)^NtX, ؾ&+n'YGU7!8'15ۆLGAY1jKV&צ-sb,/kGB3B:ziP.ĶϔI'AW0D3M)57 :IF'gJչÅAi*(:q*۷Kaj|Zgm-uVEc\.w<4C%'+1QXJ`AOsԌ6 \Mh/' gSWpx1Q~:_?"e;_`[K'8gu$ ڨ kh 0aA*-&>O!~mӃjV1F[Us VS* 7c=nߢ]Y$+@@1C7ͩTǟ<_1NnYB(wf0"K+l\HF34H^IP5ybmIb .!$T/TdT=ƠeN* WKx:26-& z)E7"? ^Z'x4&y:{!6d龿OPȄ"s @IË즘Clc*Ngˢ#;~W`7?Y>~&h'nEú2^z;c8FtQ%90̘k>OU{񉒼bY0&.\Ta"0qd. V%xV Iᗚ <#w, ɘfc՗Ýhl!IHPbVB<ֵ7UD/ #mˮT$4@gS;ߤP}Y8U*5"SjQ|y_ @WԌxoXHdeg׋yC%õnk?vb#vyi2V  pKaLJT \d];I:u8--8Hu:hvyV[y꘺/Gi7*ufٙ"VFB(`4oh˼k .WTEǡp!L^H?(O ;A aPnP\~|-M  ۡB\`K#d"HMJ+ހnWGYC\/ luh3 xyvMai/ #<$ZHkRmcWF1z4;f.„f5~m6Kչy)CZŖcfQ/k9 m:dR3@u~Roɂ:HE=HD;Ň7 w& }>n#o#w ) ۭU{Rm+sdl0#\ z9E\Ak/Rgݫ"OmzIo 9+ ,t*;{t5oH$R\gm>trBessζl6Q{p'Sf)^.VI0berE,o82l\qذng=b$ǨVxacHYa4Ч#))entry(nameException::Class::Base.3.zstnode(typeregularcontents(/d=UJ1ul׫^5K2H{yO|ҟ8d i7wR_d;LBơBez*nRzcJS_ Pv00@ LT>DŽxB< dzԛ K:p!5qpP3yȢ a ,J>2F5>uPkm:,[*Gq3,_?IrE&/g); D(ߦQʜ7A:R}|ߵq|[\(时+jӴxI)0 }FoQaC?^&(wĕ;<\#Qn0嶴QA PV6<dFH6Gp[ɟeE"H }_3{ uSޖ#<ũ}ɇs) }kVM(ɟٕ#+i$pR^6 ,mcP\X`\<쟧&J樚Q0MQm޷Jlt& &㸹A:dkcגsQvy{<Xk( G0JHʅAEK%}nCV);dc8N齌gt$*/{*dpÄfYyZw\u `*aPY^`sB8ݵר"7r8Ef5XEvι?C;Җ#_#wnZȍ1,Eǽk)7w򝚦)VBϷXn=Bx6&+E~ a#ӊ/SܪڞX?{q'`ngDqY{;o\,JY sag p(58ZsnROyvPRuJh0g:<ңezD7=c^kJhŞ>y"aF #!Nu)_*#4ؚeLٌ I @&t)㡲4pAb!H Dd$I2Mّ̓gTKGH[y(`vDtæiZNuW),s4KkxPI<•!p߰4HHCA wPJĨ$>$uʢ-ܮ vI S?E`TbDV#AYz)~_׋psΆϦ| cҮ^,p6^B-iL!HAge IAj L{~ @?= *Ft:y/Aue?~UWL*'\O . 1~"j4+XgSH(!#M*3 ۄh"bv6uv0uf&܍PHw$1 pS r^efΜMz\/j{‘ouQű(':S_&3Wsa޶*FJi++ 7][{ |)#rC$'ZBFpt eG(;Vt*l:gVV6Wii"[yƥl#A71SMJ5fԞmmt^g(WUu32c-JndscJU-VQ'^~hYoCv*[8r Z8pxd`/l\ nz"IR0̔u~0!`}rxdRjX 8y:=;Z?x}iWgKU Hil,N`3~b6S*5LWE"" {K'^G k""S됌'[ɥ n]b#\Y{0[:fؗ =zgD)i/-s]?#҆զ. "jS`bn3EsF(;Khi4U#mN&Hڱgqvo} Dz1baaJaN#u +9z+Zw,̟C([h&|HO>T59Č+\`ui&-!s:lT~ɝuSRۙ6;rH(Y W8y^Kt?>gWxE[>^o2xA`>AQ͜ApQr!+\8cItdθ.+]fC/ۘ N-%*O!z;WPNSGYjԢ$} {ض zcڝ@KXJ:@aB6kU>:2$ɴ6n\HL"TߡXµE,ރ!}-mFKt?1h/O3~DzyBTyu5]!'^q`h0G7]Og(ASIlX rkBz0%7A9ҭ85ꎈYȢ@a 2d^¶"XCeŸvD6MA0ς8'u~u>` _'͛ [GKk[:\\bMǾ~4\$y0E@$saXTw/<K.]JkZh.0|#hލt8TgJ0K T@w6lꏖ澠 o~؏ʷ&C2旗SF W>PvLO߇5q;m*TmMB:;TqW㒍E-*Cg ~U*sЦ"pN#/ԵQ& Ѩ2Olu&-sT8QS@]6KkU < _E0tNàCܗ0Ecpˇ6\}w