view release on metacpan or search on metacpan
local/lib/perl5/Future.pm view on Meta::CPAN
$future = Future->call( \&code, @args )
I<Since version 0.15.>
A convenient wrapper for calling a C<CODE> reference that is expected to
return a future. In normal circumstances is equivalent to
$future = $code->( @args )
except that if the code throws an exception, it is wrapped in a new immediate
fail future. If the return value from the code is not a blessed C<Future>
reference, an immediate fail future is returned instead to complain about this
fact.
=cut
sub call
{
my $class = shift;
my ( $code, @args ) = @_;
local/lib/perl5/Future.pm view on Meta::CPAN
=head2 done
$future->done( @result )
Marks that the leaf future is now ready, and provides a list of values as a
result. (The empty list is allowed, and still indicates the future as ready).
Cannot be called on a convergent future.
If the future is already cancelled, this request is ignored. If the future is
already complete with a result or a failure, an exception is thrown.
=cut
sub done
{
my $self = shift;
if( ref $self ) {
$self->{cancelled} and return $self;
$self->{ready} and Carp::croak "${\$self->__selfstr} is already ".$self->_state." and cannot be ->done";
local/lib/perl5/Future.pm view on Meta::CPAN
{
my $self = shift;
return sub { $self->done( @_ ) };
}
=head2 fail
$future->fail( $exception, @details )
Marks that the leaf future has failed, and provides an exception value. This
exception will be thrown by the C<get> method if called.
The exception must evaluate as a true value; false exceptions are not allowed.
Further details may be provided that will be returned by the C<failure> method
in list context. These details will not be part of the exception string raised
by C<get>.
If the future is already cancelled, this request is ignored. If the future is
already complete with a result or a failure, an exception is thrown.
=cut
sub fail
{
my $self = shift;
my ( $exception, @details ) = @_;
$_[0] or Carp::croak "$self ->fail requires an exception that is true";
local/lib/perl5/Future.pm view on Meta::CPAN
}
$self->fail( $exception, @details );
}
=head2 on_cancel
$future->on_cancel( $code )
If the future is not yet ready, adds a callback to be invoked if the future is
cancelled by the C<cancel> method. If the future is already ready, throws an
exception.
If the future is cancelled, the callbacks will be invoked in the reverse order
to that in which they were registered.
$on_cancel->( $future )
If passed another C<Future> instance, the passed instance will be cancelled
when the original future is cancelled. This method does nothing if the future
is already complete.
local/lib/perl5/Future.pm view on Meta::CPAN
$result = $future->get
If the future is ready and completed successfully, returns the list of
results that had earlier been given to the C<done> method on a leaf future,
or the list of component futures it was waiting for on a convergent future. In
scalar context it returns just the first result value.
If the future is ready but failed, this method raises as an exception the
failure string or object that was given to the C<fail> method.
If the future was cancelled an exception is thrown.
If it is not yet ready and is not of a subclass that provides an C<await>
method an exception is thrown. If it is subclassed to provide an C<await>
method then this is used to wait for the future to be ready, before returning
the result or propagating its failure exception.
=cut
sub await
{
my $self = shift;
Carp::croak "$self is not yet complete and does not provide ->await";
}
local/lib/perl5/Future.pm view on Meta::CPAN
its invocant followed by another action given by a code reference. The
combined activity waits for the first future to be ready, then may invoke the
code depending on the success or failure of the first, or may run it
regardless. The returned sequence future represents the entire combination of
activity.
In some cases the code should return a future; in some it should return an
immediate result. If a future is returned, the combined future will then wait
for the result of this second one. If the combinined future is cancelled, it
will cancel either the first future or the second, depending whether the first
had completed. If the code block throws an exception instead of returning a
value, the sequence future will fail with that exception as its message and no
further values.
As it is always a mistake to call these sequencing methods in void context and lose the
reference to the returned future (because exception/error handling would be
silently dropped), this method warns in void context.
=cut
sub _sequence
local/lib/perl5/Future.pm view on Meta::CPAN
my $f = Future->done( $value );
Similarly, the C<fail> and C<die> methods can be used to generate a C<Future>
that is immediately failed.
my $f = Future->die( "This is never going to work" );
This could be considered similarly to a C<die> call.
An C<eval{}> block can be used to turn a C<Future>-returning function that
might throw an exception, into a C<Future> that would indicate this failure.
my $f = eval { function() } || Future->fail( $@ );
This is neater handled by the C<call> class method, which wraps the call in
an C<eval{}> block and tests the result:
my $f = Future->call( \&function );
=head2 Sequencing
local/lib/perl5/Future.pm view on Meta::CPAN
->then( sub {
return do_second();
})
->then( sub {
return do_third();
});
The result of the C<$f> future itself will be the result of the future
returned by the final function, if none of them failed. If any of them fails
it will fail with the same failure. This can be considered similar to normal
exception handling in synchronous code; the first time a function call throws
an exception, the subsequent calls are not made.
=head2 Merging Control Flow
A C<wait_all> future may be used to resynchronise control flow, while waiting
for multiple concurrent operations to finish.
my $f1 = foperation( foo => "something" );
my $f2 = foperation( bar => "something else" );
local/lib/perl5/Future/Phrasebook.pod view on Meta::CPAN
Using a Future it is necessary to await the result of the first C<Future>
before calling the second.
my $f = F_FIRST()
->then( sub { F_SECOND(); } );
Here, the anonymous closure is invoked once the C<Future> returned by
C<F_FIRST()> succeeds. Because C<then> invokes the code block only if the
first Future succeeds, it shortcircuits around failures similar to the way that
C<die()> shortcircuits around thrown exceptions. A C<Future> representing the
entire combination is returned by the method.
Because the C<then> method itself returns a C<Future> representing the
overall operation, it can itself be further chained.
FIRST();
SECOND();
THIRD();
Z<>
local/lib/perl5/Future/Phrasebook.pod view on Meta::CPAN
if( $result == $value ) {
return F_ACTION();
}
else {
return $f_cond;
}
});
=head1 EXCEPTION HANDLING
In regular call/return style code, if any function throws an exception, the
remainder of the block is not executed, the containing C<try> or C<eval> is
aborted, and control is passed to the corresponding C<catch> or line after the
C<eval>.
try {
FIRST();
}
catch {
my $e = $_;
ERROR( $e );
local/lib/perl5/Future/Phrasebook.pod view on Meta::CPAN
and doesn't return a C<Future>. In that case, the C<else> code block can
return an immediate C<Future> instance.
my $f = F_FIRST()
->else( sub {
ERROR( @_ );
return Future->done;
});
Sometimes the failure handling code simply needs to be aware of the failure,
but rethrow it further up.
try {
FIRST();
}
catch {
my $e = $_;
ERROR( $e );
die $e;
};
local/lib/perl5/Future/Phrasebook.pod view on Meta::CPAN
Z<>
my $f = repeat {
F_FUNC();
} until => sub { HALTING_COND() };
=head2 Iterating with Exceptions
Technically, this loop isn't quite the same as the equivalent C<while> loop in
plain Perl, because the C<while> loop will also stop executing if the code
within it throws an exception. This can be handled in C<repeat> by testing for
a failed C<Future> in the C<until> condition.
while(1) {
TRIAL();
}
Z<>
my $f = repeat {
F_TRIAL();
local/lib/perl5/Future/Phrasebook.pod view on Meta::CPAN
give the collected results of the individual item futures, thus making them
similar to perl's C<map> operator.
Sometimes, no result is required, and the items are run in a loop simply for
some side-effect of the body.
foreach my $item ( @ITEMS ) {
FUNC( $item );
}
To avoid having to collect a potentially-large set of results only to throw
them away, the C<fmap_void> function variant of the C<fmap> family yields a
Future that completes with no result after all the items are complete.
my $f = fmap_void {
my $item = shift;
F_FIRST( $item )
} foreach => \@ITEMS, concurrent => 10;
=head1 AUTHOR
local/lib/perl5/Future/Utils.pm view on Meta::CPAN
=head1 INVOKING A BLOCK OF CODE
=head2 call
$f = call { CODE }
I<Since version 0.22.>
The C<call> function invokes a block of code that returns a future, and simply
returns the future it returned. The code is wrapped in an C<eval {}> block, so
that if it throws an exception this is turned into an immediate failed
C<Future>. If the code does not return a C<Future>, then an immediate failed
C<Future> instead.
(This is equivalent to using C<< Future->call >>, but is duplicated here for
completeness).
=cut
sub call(&)
{
local/lib/perl5/Future/Utils.pm view on Meta::CPAN
$future = repeat { CODE } while => CODE
Repeatedly calls the C<CODE> block while the C<while> condition returns a true
value. Each time the trial future completes, the C<while> condition is passed
the trial future.
$trial_f = $code->( $previous_trial_f )
$again = $while->( $trial_f )
If the C<$code> block dies entirely and throws an exception, this will be
caught and considered as an immediately-failed C<Future> with the exception as
the future's failure. The exception will not be propagated to the caller.
=head2 repeat+until
$future = repeat { CODE } until => CODE
Repeatedly calls the C<CODE> block until the C<until> condition returns a true
value. Each time the trial future completes, the C<until> condition is passed
the trial future.
local/lib/perl5/IO/Async/Function.pm view on Meta::CPAN
number of calls. (New workers may be started to replace stopped ones, within
the bounds given above).
=head2 idle_timeout => NUM
Optional. If provided, idle worker processes will be shut down after this
amount of time, if there are more than C<min_workers> of them.
=head2 exit_on_die => BOOL
Optional boolean, controls what happens after the C<code> throws an
exception. If missing or false, the worker will continue running to process
more requests. If true, the worker will be shut down. A new worker might be
constructed by the C<call> method to replace it, if necessary.
=head2 setup => ARRAY
Optional array reference. Specifies the C<setup> key to pass to the underlying
L<IO::Async::Process> when setting up new worker processes.
=cut
local/lib/perl5/IO/Async/Function.pm view on Meta::CPAN
=over 8
=item args => ARRAY
A reference to the array of arguments to pass to the code.
=back
If the function body returns normally the list of results are provided as the
(successful) result of returned future. If the function throws an exception
this results in a failed future. In the special case that the exception is in
fact an unblessed C<ARRAY> reference, this array is unpacked and used as-is
for the C<fail> result. If the exception is not such a reference, it is used
as the first argument to C<fail>, in the category of C<error>.
$f->done( @result )
$f->fail( @{ $exception } )
$f->fail( $exception, error => )
local/lib/perl5/IO/Async/Handle.pm view on Meta::CPAN
=head2 socket
$handle->socket( $ai )
Convenient shortcut to creating a socket handle, as given by an addrinfo
structure, and setting it as the read and write handle for the object.
C<$ai> may be either a C<HASH> or C<ARRAY> reference of the same form as given
to L<IO::Async::OS>'s C<extract_addrinfo> method.
This method returns nothing if it succeeds, or throws an exception if it
fails.
=cut
sub socket
{
my $self = shift;
my ( $ai ) = @_;
# TODO: Something about closing the old one?
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
=head1 MAGIC CONSTRUCTOR
=head2 new
$loop = IO::Async::Loop->new
This function attempts to find a good subclass to use, then calls its
constructor. It works by making a list of likely candidate classes, then
trying each one in turn, C<require>ing the module then calling its C<new>
method. If either of these operations fails, the next subclass is tried. If
no class was successful, then an exception is thrown.
The constructed object is cached, and will be returned again by a subsequent
call. The cache will also be set by a constructor on a specific subclass. This
behaviour makes it possible to simply use the normal constructor in a module
that wishes to interract with the main program's Loop, such as an integration
module for another event system.
For example, the following two C<$loop> variables will refer to the same
object:
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
This option is now discouraged in favour of the L<IO::Async::OS> hint instead.
At some future point it may be removed entirely, given as currently only
C<linux> uses it.
=item * Poll and Select
Finally, if no other choice has been made by now, the built-in C<Poll> module
is chosen. This should always work, but in case it doesn't, the C<Select>
module will be chosen afterwards as a last-case attempt. If this also fails,
then the magic constructor itself will throw an exception.
=back
If any of the explicitly-requested loop types (C<$ENV{IO_ASYNC_LOOP}> or
C<$IO::Async::Loop::LOOP>) fails to load then a warning is printed detailing
the error.
Implementors of new C<IO::Async::Loop> subclasses should see the notes about
C<API_VERSION> below.
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
A continuation to be called when the child process exits and has closed all of
the filehandles that were set up for it. It will be invoked in the following
way:
$on_finish->( $pid, $exitcode )
The second argument is passed the plain perl C<$?> value.
=item on_error => CODE
Optional continuation to be called when the child code block throws an
exception, or the command could not be C<exec(2)>ed. It will be invoked in the
following way (as per C<spawn>)
$on_error->( $pid, $exitcode, $dollarbang, $dollarat )
If this continuation is not supplied, then C<on_finish> is used instead. The
value of C<$!> and C<$@> will not be reported.
=item setup => ARRAY
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
C<on_joined> callback. It is called inside an C<eval> block; if it fails the
exception will be caught.
=item context => "scalar" | "list" | "void"
Optional. Gives the calling context that C<code> is invoked in. Defaults to
C<scalar> if not supplied.
=item on_joined => CODE
Callback to invoke when the thread function returns or throws an exception.
If it returned, this callback will be invoked with its result
$on_joined->( return => @result )
If it threw an exception the callback is invoked with the value of C<$@>
$on_joined->( died => $! )
=back
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
=item IO_ASYNC_WATCHDOG_INTERVAL => INT
Watchdog interval, in seconds, to pass to the C<alarm(2)> call. Defaults to 10
seconds.
=item IO_ASYNC_WATCHDOG_SIGABRT => BOOL
If enabled, the watchdog signal handler will raise a C<SIGABRT>, which usually
has the effect of breaking out of a running program in debuggers such as
F<gdb>. If not set then the process is terminated by throwing an exception with
C<die>.
=back
=cut
=head1 AUTHOR
Paul Evans <leonerd@leonerd.org.uk>
local/lib/perl5/IO/Async/Notifier.pm view on Meta::CPAN
=head2 configure
$notifier->configure( %params )
This method is called by the constructor to set the initial values of named
parameters, and by users of the object to adjust the values once constructed.
This method should C<delete> from the C<%params> hash any keys it has dealt
with, then pass the remaining ones to the C<SUPER::configure>. The base
class implementation will throw an exception if there are any unrecognised
keys remaining.
=cut
=head2 configure_unknown
$notifier->configure_unknown( %params )
This method is called by the base class C<configure> method, for any remaining
parameters that are not recognised. The default implementation throws an
exception using C<Carp> that lists the unrecognised keys. This method is
provided to allow subclasses to override the behaviour, perhaps to store
unrecognised keys, or to otherwise inspect the left-over arguments for some
other purpose.
=cut
=head2 _add_to_loop
$notifier->_add_to_loop( $loop )
local/lib/perl5/IO/Async/Notifier.pm view on Meta::CPAN
goto &$code;
}
);
}
=head2 maybe_make_event_cb
$callback = $notifier->maybe_make_event_cb( $event_name )
Similar to C<make_event_cb> but will return C<undef> if the object cannot
handle the named event, rather than throwing an exception.
=cut
sub maybe_make_event_cb
{
my $self = shift;
my ( $event_name ) = @_;
my $code = $self->can_event( $event_name )
or return undef;
local/lib/perl5/IO/Async/Notifier.pm view on Meta::CPAN
$self->_debug_printf_event( scalar caller, $event_name ) if $IO::Async::Debug::DEBUG;
return $code->( $self, @args );
}
=head2 maybe_invoke_event
$retref = $notifier->maybe_invoke_event( $event_name, @args )
Similar to C<invoke_event> but will return C<undef> if the object cannot
handle the name event, rather than throwing an exception. In order to
distinguish this from an event-handling function that simply returned
C<undef>, if the object does handle the event, the list that it returns will
be returned in an ARRAY reference.
=cut
sub maybe_invoke_event
{
my $self = shift;
my ( $event_name, @args ) = @_;
local/lib/perl5/IO/Async/Notifier.pm view on Meta::CPAN
);
}
}
=head2 invoke_error
$notifier->invoke_error( $message, $name, @details )
Invokes the stored C<on_error> event handler, passing in the given arguments.
If no handler is defined, it will be passed up to the containing parent
notifier, if one exists. If no parent exists, the error message will be thrown
as an exception by using C<die()> and this method will not return.
If a handler is found to handle this error, the method will return as normal.
However, as the expected use-case is to handle "fatal" errors that now render
the notifier unsuitable to continue, code should be careful not to perform any
further work after invoking it. Specifically, sockets may become disconnected,
or the entire notifier may now be removed from its containing loop.
The C<$name> and C<@details> list should follow similar semantics to L<Future>
failures. That is, the C<$name> should be a string giving a category of
local/lib/perl5/IO/Async/Process.pm view on Meta::CPAN
{
my $self = shift;
return defined $self->{exitcode} ? ( $self->{exitcode} >> 8 ) : undef;
}
=head2 exception
$exception = $process->exception
If the process exited due to an exception, returns the exception that was
thrown. Otherwise, returns C<undef>.
=cut
sub exception
{
my $self = shift;
return $self->{dollarat};
}
=head2 errno
$errno = $process->errno
If the process exited due to an exception, returns the numerical value of
C<$!> at the time the exception was thrown. Otherwise, returns C<undef>.
=cut
sub errno
{
my $self = shift;
return $self->{dollarbang}+0;
}
=head2 errstr
$errstr = $process->errstr
If the process exited due to an exception, returns the string value of
C<$!> at the time the exception was thrown. Otherwise, returns C<undef>.
=cut
sub errstr
{
my $self = shift;
return $self->{dollarbang}."";
}
=head2 fd
local/lib/perl5/IO/Async/Resolver.pm view on Meta::CPAN
=item on_resolved => CODE
A continuation that is invoked when the resolver function returns a successful
result. It will be passed the array returned by the resolver function.
$on_resolved->( @result )
=item on_error => CODE
A continuation that is invoked when the resolver function fails. It will be
passed the exception thrown by the function.
=back
=cut
sub resolve
{
my $self = shift;
my %args = @_;
local/lib/perl5/IO/Async/Resolver.pm view on Meta::CPAN
=item $name
The name of the resolver function; must be a plain string. This name will be
used by the C<type> argument to the C<resolve> method, to identify it.
=item $code
A CODE reference to the resolver function body. It will be called in list
context, being passed the list of arguments given in the C<data> argument to
the C<resolve> method. The returned list will be passed to the
C<on_resolved> callback. If the code throws an exception at call time, it will
be passed to the C<on_error> continuation. If it returns normally, the list of
values it returns will be passed to C<on_resolved>.
=back
=cut
# Plain function, not a method
sub register_resolver
{
local/lib/perl5/IO/Async/Test.pm view on Meta::CPAN
=head2 wait_for
wait_for { COND }
Repeatedly call the C<loop_once> method on the underlying loop (given to the
C<testing_loop> function), until the given condition function callback
returns true.
To guard against stalled scripts, if the loop indicates a timeout for 10
consequentive seconds, then an error is thrown.
=cut
sub wait_for(&)
{
my ( $cond ) = @_;
my ( undef, $callerfile, $callerline ) = caller;
my $timedout = 0;
local/lib/perl5/Module/Build/API.pod view on Meta::CPAN
print STDERR "HEY, ARE YOU LISTENING??\n" if $loud;
print "We'll use the ", $build->args('Dbd'), " DBI driver\n";
print "Are you sure you want that many?\n"
if $build->args('Quantity') > 2;
The arguments for such a specification can be called like so:
perl Build.PL --Loud --Dbd=DBD::pg --Quantity --Quantity --Quantity
B<WARNING:> Any option specifications that conflict with Module::Build's own
options (defined by its properties) will throw an exception. Use capitalized
option names to avoid unintended conflicts with future Module::Build options.
Consult the Getopt::Long documentation for details on its usage.
=item include_dirs
[version 0.24]
Specifies any additional directories in which to search for C header
files. May be given as a string indicating a single directory, or as
local/lib/perl5/Module/Build/API.pod view on Meta::CPAN
otherwise. This is handy for actions defined (or maybe not!) in subclasses.
[version 0.32_xx]
=item cbuilder()
[version 0.2809]
Returns the internal ExtUtils::CBuilder object that can be used for
compiling & linking C code. If no such object is available (e.g. if
the system has no compiler installed) an exception will be thrown.
=item check_installed_status($module, $version)
[version 0.11]
This method returns a hash reference indicating whether a version
dependency on a certain module is satisfied. The C<$module> argument
is given as a string like C<"Data::Dumper"> or C<"perl">, and the
C<$version> argument can take any of the forms described in L</requires>
above. This allows very fine-grained version checking.
local/lib/perl5/Module/Build/Authoring.pod view on Meta::CPAN
One advantage of Module::Build is that since it's implemented as Perl
methods, you can invoke these methods directly if you want to install
a module non-interactively. For instance, the following Perl script
will invoke the entire build/install procedure:
my $build = Module::Build->new(module_name => 'MyModule');
$build->dispatch('build');
$build->dispatch('test');
$build->dispatch('install');
If any of these steps encounters an error, it will throw a fatal
exception.
You can also pass arguments as part of the build process:
my $build = Module::Build->new(module_name => 'MyModule');
$build->dispatch('build');
$build->dispatch('test', verbose => 1);
$build->dispatch('install', sitelib => '/my/secret/place/');
Building and installing modules in this way skips creating the
local/lib/perl5/Module/Build/Compat.pm view on Meta::CPAN
license => 'perl',
create_makefile_pl => 'traditional' );
...
=head1 DESCRIPTION
Because C<ExtUtils::MakeMaker> has been the standard way to distribute
modules for a long time, many tools (CPAN.pm, or your system
administrator) may expect to find a working F<Makefile.PL> in every
distribution they download from CPAN. If you want to throw them a
bone, you can use C<Module::Build::Compat> to automatically generate a
F<Makefile.PL> for you, in one of several different styles.
C<Module::Build::Compat> also provides some code that helps out the
F<Makefile.PL> at runtime.
=head1 METHODS
=over 4
local/lib/perl5/Struct/Dumb.pm view on Meta::CPAN
usage: main::Point($x, $y) at -e line 1
$ perl -E 'use Struct::Dumb; struct Point => [qw( x y )]; Point(10,20)->z'
main::Point does not have a 'z' field at -e line 1
$ perl -E 'use Struct::Dumb; struct Point => [qw( x y )]; Point(1,2)->x(3)'
main::Point->x invoked with arguments at -e line 1.
Objects in this class are (currently) backed by an ARRAY reference store,
though this is an internal implementation detail and should not be relied on
by using code. Attempting to dereference the object as an ARRAY will throw an
exception.
=head2 CONSTRUCTOR FORMS
The C<struct> and C<readonly_struct> declarations create two different kinds
of constructor function, depending on the setting of the C<named_constructor>
option. When false, the constructor takes positional values in the same order
as the fields were declared. When true, the constructor takes a key/value pair
list in no particular order, giving the value of each named field.
local/lib/perl5/Test/Exception.pm view on Meta::CPAN
use warnings;
package Test::Exception;
use Test::Builder;
use Sub::Uplevel qw( uplevel );
use base qw( Exporter );
our $VERSION = '0.43';
$VERSION = eval $VERSION;
our @EXPORT = qw(dies_ok lives_ok throws_ok lives_and);
my $Tester = Test::Builder->new;
sub import {
my $self = shift;
if ( @_ ) {
my $package = caller;
$Tester->exported_to( $package );
$Tester->plan( @_ );
};
local/lib/perl5/Test/Exception.pm view on Meta::CPAN
use Test::More tests => 5;
use Test::Exception;
# or if you don't need Test::More
use Test::Exception tests => 5;
# then...
# Check that the stringified exception matches given regex
throws_ok { $foo->method } qr/division by zero/, 'zero caught okay';
# Check an exception of the given class (or subclass) is thrown
throws_ok { $foo->method } 'Error::Simple', 'simple error thrown';
# all Test::Exceptions subroutines are guaranteed to preserve the state
# of $@ so you can do things like this after throws_ok and dies_ok
like $@, 'what the stringified exception should look like';
# Check that something died - we do not care why
dies_ok { $foo->method } 'expecting to die';
# Check that something did not die
lives_ok { $foo->method } 'expecting to live';
# Check that a test runs without an exception
lives_and { is $foo->method, 42 } 'method is 42';
# or if you don't like prototyped functions
throws_ok( sub { $foo->method }, qr/division by zero/,
'zero caught okay' );
throws_ok( sub { $foo->method }, 'Error::Simple',
'simple error thrown' );
dies_ok( sub { $foo->method }, 'expecting to die' );
lives_ok( sub { $foo->method }, 'expecting to live' );
lives_and( sub { is $foo->method, 42 }, 'method is 42' );
=head1 DESCRIPTION
This module provides a few convenience methods for testing exception based code. It is built with
L<Test::Builder> and plays happily with L<Test::More> and friends.
local/lib/perl5/Test/Exception.pm view on Meta::CPAN
package DB;
if( wantarray ) {
if ( !@_ ) {
return (CORE::caller($height))[0..2];
}
else {
# If we got here, we are within a Test::Exception test, and
# something is producing a stacktrace. In case this is a full
# trace (i.e. confess() ), we have to make sure that the sub
# args are not visible. If we do not do this, and the test in
# question is throws_ok() with a regex, it will end up matching
# against itself in the args to throws_ok().
#
# While it is possible (and maybe wise), to test if we are
# indeed running under throws_ok (by crawling the stack right
# up from here), the old behavior of Test::Exception was to
# simply obliterate @DB::args altogether in _quiet_caller, so
# we are just preserving the behavior to avoid surprises
#
my @frame_info = CORE::caller($height);
@DB::args = ();
return @frame_info;
}
}
local/lib/perl5/Test/Exception.pm view on Meta::CPAN
my $class = ref $exception;
$exception = "$class ($exception)"
if $class && "$exception" !~ m/^\Q$class/;
chomp $exception;
return "$prefix $exception";
};
=over 4
=item B<throws_ok>
Tests to see that a specific exception is thrown. throws_ok() has two forms:
throws_ok BLOCK REGEX, TEST_DESCRIPTION
throws_ok BLOCK CLASS, TEST_DESCRIPTION
In the first form the test passes if the stringified exception matches the give regular expression. For example:
throws_ok { read_file( 'unreadable' ) } qr/No file/, 'no file';
If your perl does not support C<qr//> you can also pass a regex-like string, for example:
throws_ok { read_file( 'unreadable' ) } '/No file/', 'no file';
The second form of throws_ok() test passes if the exception is of the same class as the one supplied, or a subclass of that class. For example:
throws_ok { $foo->bar } "Error::Simple", 'simple error';
Will only pass if the C<bar> method throws an Error::Simple exception, or a subclass of an Error::Simple exception.
You can get the same effect by passing an instance of the exception you want to look for. The following is equivalent to the previous example:
my $SIMPLE = Error::Simple->new;
throws_ok { $foo->bar } $SIMPLE, 'simple error';
Should a throws_ok() test fail it produces appropriate diagnostic messages. For example:
not ok 3 - simple error
# Failed test (test.t at line 48)
# expecting: Error::Simple exception
# found: normal exit
Like all other Test::Exception functions you can avoid prototypes by passing a subroutine explicitly:
throws_ok( sub {$foo->bar}, "Error::Simple", 'simple error' );
A true value is returned if the test succeeds, false otherwise. On exit $@ is guaranteed to be the cause of death (if any).
A description of the exception being checked is used if no optional test description is passed.
NOTE: Remember when you C<die $string_without_a_trailing_newline> perl will
automatically add the current script line number, input line number and a newline. This will
form part of the string that throws_ok regular expressions match against.
=cut
sub throws_ok (&$;$) {
my ( $coderef, $expecting, $description ) = @_;
unless (defined $expecting) {
require Carp;
Carp::croak( "throws_ok: must pass exception class/object or regex" );
}
$description = _exception_as_string( "threw", $expecting )
unless defined $description;
my $exception = _try_as_caller( $coderef );
my $regex = $Tester->maybe_regex( $expecting );
my $ok = $regex
? ( $exception =~ m/$regex/ )
: eval {
$exception->isa( ref $expecting ? ref $expecting : $expecting )
};
local/lib/perl5/Test/Exception.pm view on Meta::CPAN
return $a / $b;
};
dies_ok { div( 1, 0 ) } 'divide by zero detected';
# or if you don't like prototypes
dies_ok( sub { div( 1, 0 ) }, 'divide by zero detected' );
A true value is returned if the test succeeds, false otherwise. On exit $@ is guaranteed to be the cause of death (if any).
Remember: This test will pass if the code dies for any reason. If you care about the reason it might be more sensible to write a more specific test using throws_ok().
The test description is optional, but recommended.
=cut
sub dies_ok (&;$) {
my ( $coderef, $description ) = @_;
my $exception = _try_as_caller( $coderef );
my $ok = $Tester->ok( _is_exception($exception), $description );
$@ = $exception;
local/lib/perl5/Test/Exception.pm view on Meta::CPAN
my $exception = _try_as_caller( $coderef );
my $ok = $Tester->ok( ! _is_exception( $exception ), $description );
$Tester->diag( _exception_as_string( "died:", $exception ) ) unless $ok;
$@ = $exception;
return $ok;
}
=item B<lives_and>
Run a test that may throw an exception. For example, instead of doing:
my $file;
lives_ok { $file = read_file('answer.txt') } 'read_file worked';
is $file, "42", 'answer was 42';
You can use lives_and() like this:
lives_and { is read_file('answer.txt'), "42" } 'answer is 42';
# or if you don't like prototypes
lives_and(sub {is read_file('answer.txt'), "42"}, 'answer is 42');
local/lib/perl5/Test/Exception.pm view on Meta::CPAN
plan tests => 2;
# ... tests that need Test::Exception ...
Note that we load Test::Exception in a C<BEGIN> block ensuring that the subroutine prototypes are in place before the rest of the test script is compiled.
=head1 BUGS
There are some edge cases in Perl's exception handling where Test::Exception will miss exceptions
thrown in DESTROY blocks. See the RT bug L<http://rt.cpan.org/Ticket/Display.html?id=24678> for
details, along with the t/edge-cases.t in the distribution test suite. These will be addressed in
a future Test::Exception release.
If you find any more bugs please let me know by e-mail, or report the problem with
L<http://rt.cpan.org/>.
=head1 COMMUNITY
=over 4
t/invalid.t view on Meta::CPAN
use Acme::Sort::Sleep qw( sleepsort );
use Test::More;
use Test::Exception;
my $error = qr/Only positive numbers accepted./;
my @undefined = ( undef );
my @negative = ( -1 );
my @non_numeric = ( 'z' );
throws_ok { sleepsort( @undefined ) } $error, 'undef';
throws_ok { sleepsort( @negative ) } $error, 'negative number';
throws_ok { sleepsort( @non_numeric ) } $error, 'non-numeric value';
done_testing;