Skip Menu |

This queue is for tickets about the Scalar-List-Utils CPAN distribution.

Report information
The Basics
Id: 72080
Status: resolved
Priority: 0/
Queue: Scalar-List-Utils

People
Owner: Nobody in particular
Requestors: user42 [...] zip.com.au
Cc:
AdminCc:

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



Subject: set_prototype() and get-magic
Date: Tue, 01 Nov 2011 11:28:41 +1100
To: bug-Scalar-List-Utils [...] rt.cpan.org
From: Kevin Ryde <user42 [...] zip.com.au>
Nosing around ListUtil.xs set_prototype() I saw if (SvROK(subref)) { without running get-magic on that subref, it seems. Should it do the magic so a tied scalar for the coderef will work, such as foo.pl below which gets Scalar::Util 1.2303 set_prototype: not a reference at /tmp/foo.pl line 25. where I though it might run the FETCH of MyTie and act on the \&my_subr established there.
#!/usr/bin/perl -w use strict; use Scalar::Util; print "Scalar::Util $Scalar::Util::VERSION\n"; { package MyTie; sub TIESCALAR { my $class = shift; return bless {@_}, $class; } sub FETCH { return \&my_subr; } sub my_subr { } } my $foo; tie $foo, 'MyTie'; # print $foo,"\n"; &Scalar::Util::set_prototype ($foo, '$$'); print prototype($foo),"\n"; exit 0;
On Mon Oct 31 20:29:12 2011, user42@zip.com.au wrote: Show quoted text
> Nosing around ListUtil.xs set_prototype() I saw > > if (SvROK(subref)) { > > without running get-magic on that subref, it seems. Should it do the > magic so a tied scalar for the coderef will work, such as foo.pl below > which gets > > Scalar::Util 1.2303 > set_prototype: not a reference at /tmp/foo.pl line 25. > > where I though it might run the FETCH of MyTie and act on the \&my_subr > established there.
Indeed it should. Thanks for the test; applied it and a fix. See attached patch. -- Paul Evans
Subject: rt72080.patch
diff --git a/ListUtil.xs b/ListUtil.xs index 84be2f1..e6a2eaa 100644 --- a/ListUtil.xs +++ b/ListUtil.xs @@ -1094,6 +1094,7 @@ set_prototype(subref, proto) PROTOTYPE: &$ CODE: { + SvGETMAGIC(subref); if(SvROK(subref)) { SV *sv = SvRV(subref); if(SvTYPE(sv) != SVt_PVCV) { diff --git a/t/proto.t b/t/proto.t index 6aa2787..e9b653a 100644 --- a/t/proto.t +++ b/t/proto.t @@ -6,7 +6,7 @@ use warnings; use Scalar::Util (); use Test::More (grep { /set_prototype/ } @Scalar::Util::EXPORT_FAIL) ? (skip_all => 'set_prototype requires XS version') - : (tests => 13); + : (tests => 14); Scalar::Util->import('set_prototype'); @@ -47,3 +47,24 @@ ok($@ =~ /^set_prototype: not a reference/, 'not a reference'); eval { &set_prototype( \'f', '' ); }; ok($@ =~ /^set_prototype: not a subroutine reference/, 'not a sub reference'); + +# RT 72080 + +{ + package TiedCV; + sub TIESCALAR { + my $class = shift; + return bless {@_}, $class; + } + sub FETCH { + return \&my_subr; + } + sub my_subr { + } +} + +my $cv; +tie $cv, 'TiedCV'; + +&Scalar::Util::set_prototype($cv, '$$'); +is( prototype($cv), '$$', 'set_prototype() on tied CV ref' );
Released in 1.39 -- Paul Evans