view release on metacpan or search on metacpan
t/lib/Sub/Uplevel.pm view on Meta::CPAN
sub bar {
uplevel 1, \&foo;
}
#line 11
bar(); # main - foo.plx - 11
=head1 DESCRIPTION
Like Tcl's uplevel() function, but not quite so dangerous. The idea
is just to fool caller(). All the really naughty bits of Tcl's
uplevel() are avoided.
B<THIS IS NOT THE SORT OF THING YOU WANT TO DO EVERYDAY>
=over 4
=item B<uplevel>
uplevel $num_frames, \&func, @args;
Makes the given function think it's being executed $num_frames higher
than the current stack level. So when they use caller($frames) it
will actually give caller($frames + $num_frames) for them.
C<uplevel(1, \&some_func, @_)> is effectively C<goto &some_func> but
you don't immediately exit the current subroutine. So while you can't
do this:
sub wrapper {
print "Before\n";
goto &some_func;
print "After\n";
}
t/lib/Sub/Uplevel.pm view on Meta::CPAN
sub _setup_CORE_GLOBAL {
no warnings 'redefine';
*CORE::GLOBAL::caller = sub(;$) {
my $height = $_[0] || 0;
# shortcut if no uplevels have been called
# always add +1 to CORE::caller to skip this function's caller
return CORE::caller( $height + 1 ) if ! @Up_Frames;
=begin _private
So it has to work like this:
Call stack Actual uplevel 1
CORE::GLOBAL::caller
Carp::short_error_loc 0
Carp::shortmess_heavy 1 0
Carp::croak 2 1
try_croak 3 2
uplevel 4
function_that_called_uplevel 5
caller_we_want_to_see 6 3
its_caller 7 4
So when caller(X) winds up below uplevel(), it only has to use
CORE::caller(X+1) (to skip CORE::GLOBAL::caller). But when caller(X)
winds up no or above uplevel(), it's CORE::caller(X+1+uplevel+1).
Which means I'm probably going to have to do something nasty like walk
up the call stack on each caller() to see if I'm going to wind up
before or after Sub::Uplevel::uplevel().
=end _private
=begin _dagolden
I found the description above a bit confusing. Instead, this is the logic
that I found clearer when CORE::GLOBAL::caller is invoked and we have to
walk up the call stack:
t/lib/Sub/Uplevel.pm view on Meta::CPAN
=cut
my $saw_uplevel = 0;
my $adjust = 0;
# walk up the call stack to fight the right package level to return;
# look one higher than requested for each call to uplevel found
# and adjust by the amount found in the Up_Frames stack for that call
for ( my $up = 0; $up <= $height + $adjust; $up++ ) {
my @caller = CORE::caller($up + 1);
if( defined $caller[0] && $caller[0] eq __PACKAGE__ ) {
# add one for each uplevel call seen
# and look into the uplevel stack for the offset
$adjust += 1 + $Up_Frames[$saw_uplevel];
$saw_uplevel++;
}
}
my @caller = CORE::caller($height + $adjust + 1);
if( wantarray ) {
if( !@_ ) {
@caller = @caller[0..2];
}
return @caller;
}
else {
return $caller[0];
}
t/lib/Test/Builder.pm view on Meta::CPAN
%s
%s
%s
DIAGNOSTIC
}
sub _caller_context {
my $self = shift;
my($pack, $file, $line) = $self->caller(1);
my $code = '';
$code .= "#line $line $file\n" if defined $file and defined $line;
return $code;
}
=item B<BAIL_OUT>
t/lib/Test/Builder.pm view on Meta::CPAN
Sometimes there is some confusion about where todo() should be looking
for the $TODO variable. If you want to be sure, tell it explicitly
what $pack to use.
=cut
sub todo {
my($self, $pack) = @_;
$pack = $pack || $self->exported_to || $self->caller($Level);
return 0 unless $pack;
no strict 'refs';
return defined ${$pack.'::TODO'} ? ${$pack.'::TODO'}
: 0;
}
=item B<caller>
my $package = $Test->caller;
my($pack, $file, $line) = $Test->caller;
my($pack, $file, $line) = $Test->caller($height);
Like the normal caller(), except it reports according to your level().
=cut
sub caller {
my($self, $height) = @_;
$height ||= 0;
my @caller = CORE::caller($self->level + $height + 1);
return wantarray ? @caller : $caller[0];
}
=back
=cut
=begin _private
=over 4
t/lib/Test/Builder.pm view on Meta::CPAN
=end _private
=cut
$SIG{__DIE__} = sub {
# We don't want to muck with death in an eval, but $^S isn't
# totally reliable. 5.005_03 and 5.6.1 both do the wrong thing
# with it. Instead, we use caller. This also means it runs under
# 5.004!
my $in_eval = 0;
for( my $stack = 1; my $sub = (CORE::caller($stack))[3]; $stack++ ) {
$in_eval = 1 if $sub =~ /^\(eval\)/;
}
$Test->{Test_Died} = 1 unless $in_eval;
};
sub _ending {
my $self = shift;
$self->_sanity_check();
t/lib/Test/Builder/Module.pm view on Meta::CPAN
$VERSION = '0.03';
use strict;
# 5.004's Exporter doesn't have export_to_level.
my $_export_to_level = sub {
my $pkg = shift;
my $level = shift;
(undef) = shift; # redundant arg
my $callpkg = caller($level);
$pkg->export($callpkg, @_);
};
=head1 NAME
Test::Builder::Module - Base class for test modules
=head1 SYNOPSIS
t/lib/Test/Builder/Tester.pm view on Meta::CPAN
# _export_to_level and import stolen directly from Test::More. I am
# the king of cargo cult programming ;-)
# 5.004's Exporter doesn't have export_to_level.
sub _export_to_level
{
my $pkg = shift;
my $level = shift;
(undef) = shift; # XXX redundant arg
my $callpkg = caller($level);
$pkg->export($callpkg, @_);
}
sub import {
my $class = shift;
my(@plan) = @_;
my $caller = caller;
$t->exported_to($caller);
t/lib/Test/Exception.pm view on Meta::CPAN
A true value is returned if the test succeeds, false otherwise. On exit $@ is guaranteed to be the cause of death (if any).
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;
return $ok;
}
=item B<lives_ok>
Checks that a piece of code exits normally, and doesn't die. For example:
t/lib/Test/Exception.pm view on Meta::CPAN
# died: open failed (No such file or directory)
A true value is returned if the test succeeds, false otherwise. On exit $@ is guaranteed to be the cause of death (if any).
The test description is optional, but recommended.
=cut
sub lives_ok (&;$) {
my ( $coderef, $description ) = @_;
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<throws_ok>
Tests to see that a specific exception is thrown. throws_ok() has two forms:
t/lib/Test/Exception.pm view on Meta::CPAN
=cut
sub throws_ok (&$;$) {
my ( $coderef, $expecting, $description ) = @_;
croak "throws_ok: must pass exception class/object or regex"
unless defined $expecting;
$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 )
};
$Tester->ok( $ok, $description );
unless ( $ok ) {
$Tester->diag( _exception_as_string( "expecting:", $expecting ) );
$Tester->diag( _exception_as_string( "found:", $exception ) );
t/lib/Test/More.pm view on Meta::CPAN
use 5.004;
use strict;
# Can't use Carp because it might cause use_ok() to accidentally succeed
# even though the module being used forgot to use Carp. Yes, this
# actually happened.
sub _carp {
my($file, $line) = (caller(1))[1,2];
warn @_, " at $file line $line\n";
}
use vars qw($VERSION @ISA @EXPORT %EXPORT_TAGS $TODO);
$VERSION = '0.64';
$VERSION = eval $VERSION; # make the alpha version come out as a number
use Test::Builder::Module;
t/lib/Test/Warn.pm view on Meta::CPAN
*warning_is = *warnings_are;
sub warnings_are (&$;$) {
my $block = shift;
my @exp_warning = map {_canonical_exp_warning($_)}
_to_array_if_necessary( shift() || [] );
my $testname = shift;
my @got_warning = ();
local $SIG{__WARN__} = sub {
my ($called_from) = caller(0); # to find out Carping methods
push @got_warning, _canonical_got_warning($called_from, shift());
};
uplevel 2,$block;
my $ok = _cmp_is( \@got_warning, \@exp_warning );
$Tester->ok( $ok, $testname );
$ok or _diag_found_warning(@got_warning),
_diag_exp_warning(@exp_warning);
return $ok;
}
*warning_like = *warnings_like;
sub warnings_like (&$;$) {
my $block = shift;
my @exp_warning = map {_canonical_exp_warning($_)}
_to_array_if_necessary( shift() || [] );
my $testname = shift;
my @got_warning = ();
local $SIG{__WARN__} = sub {
my ($called_from) = caller(0); # to find out Carping methods
push @got_warning, _canonical_got_warning($called_from, shift());
};
uplevel 2,$block;
my $ok = _cmp_like( \@got_warning, \@exp_warning );
$Tester->ok( $ok, $testname );
$ok or _diag_found_warning(@got_warning),
_diag_exp_warning(@exp_warning);
return $ok;
}