Skip Menu |

This queue is for tickets about the Contextual-Return CPAN distribution.

Report information
The Basics
Id: 26101
Status: open
Priority: 0/
Queue: Contextual-Return

People
Owner: Nobody in particular
Requestors: mschwern [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: (no value)
Fixed in: (no value)



Subject: [PATCH] Fix caller() emulation
Contextual::Return's emulation of caller() is slightly wrong in two ways. 1) It does not declare a prototype for its caller, which should be (;$), so that passing it a list causes a different behavior. It uses the first argument rather than the scalar value of the list. 2) If you do not pass it an argument it still returns 10 values, it should only return 3. The attached patch fixes this.
Subject: caller_with_args.patch
=== MANIFEST ================================================================== --- MANIFEST (revision 27911) +++ MANIFEST (local) @@ -29,4 +29,5 @@ t/RECOVER_exception_RESULT.t t/args_RESULT.t t/caller.t +t/check_caller.t t/simple_RESULT.t === lib/Contextual/Return.pm ================================================================== --- lib/Contextual/Return.pm (revision 27911) +++ lib/Contextual/Return.pm (local) @@ -4,11 +4,18 @@ BEGIN { no warnings 'redefine'; - *CORE::GLOBAL::caller = sub { - my ($uplevels) = shift || 0; - return CORE::caller($uplevels + 2 + $Contextual::Return::uplevel) - if $Contextual::Return::uplevel; - return CORE::caller($uplevels + 1); + *CORE::GLOBAL::caller = sub (;$) { + my ($uplevels) = $_[0] || 0; + $uplevels += $Contextual::Return::uplevel + ? 2 + $Contextual::Return::uplevel + : 1; + + if( wantarray and !@_ ) { + return (CORE::caller($uplevels))[0..2]; + } + else { + return CORE::caller($uplevels); + } }; use Carp; === t/check_caller.t ================================================================== --- t/check_caller.t (revision 27911) +++ t/check_caller.t (local) @@ -0,0 +1,42 @@ +#!/usr/bin/perl -w + +use Test::More 'no_plan'; + +use Contextual::Return; + +sub caller_no_args { + caller; +} + +sub core_caller_no_args { + CORE::caller; +} + +sub caller_with_args { + caller(0); +} + +sub core_caller_with_args { + CORE::caller(0); +} + +sub caller_with_list { + my @args = (0); + caller @args; +} + +sub core_caller_with_list { + my @args = (0); + CORE::caller(@args); +} + +# Keep the calls on the same line so caller() comes out the same. +is_deeply [caller_no_args], [core_caller_no_args], + "caller with no args returns right values"; + +# Skip over the "subroutine" argument since it will be different +is_deeply [ (caller_with_args)[0..2,4..9] ], [ (core_caller_with_args)[0..2,4..9] ], + "caller with args returns right values"; + +is_deeply [caller_with_list], [core_caller_with_list], + "caller with a list returns right values";
On Wed Apr 04 13:22:49 2007, MSCHWERN wrote: Show quoted text
> Contextual::Return's emulation of caller() is slightly wrong in two ways. > > 1) It does not declare a prototype for its caller, which should be (;$), > so that passing it a list causes a different behavior. It uses the > first argument rather than the scalar value of the list. > > 2) If you do not pass it an argument it still returns 10 values, it > should only return 3. > > The attached patch fixes this.
A ping as this ticket was probably created while RT was not sending out mail.