Skip Menu |

This queue is for tickets about the namespace-clean CPAN distribution.

Report information
The Basics
Id: 95298
Status: resolved
Priority: 0/
Queue: namespace-clean

People
Owner: Nobody in particular
Requestors: victor [...] vsespb.ru
Cc:
AdminCc:

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



Subject: cannot redefine subroutine by symbolic ref when namespace::clean is in use
I.pm file === package I; use Exporter 'import'; our @EXPORT = ('mysub'); sub mysub { print "Hello1\n"; } === main script: === package A; use I; use namespace::clean; package main; use strict; use warnings; no strict 'refs'; no warnings 'redefine'; A::mysub(); *A::mysub = sub { print "Hello2\n"; }; A::mysub(); my $s = 'A::mysub'; *$s = sub { print "Hello3\n"; }; A::mysub(); === outputs Hello1 Hello2 Hello2 but it should output Hello1 Hello2 Hello3 (and it does, if comment out namespace::clean). so seems subroutines cannot be redefined if accessed by symbolic ref (actually it makes use of testing/mocking modules like Test::Spec complicated)
Subject: Re: [rt.cpan.org #95298] cannot redefine subroutine by symbolic ref when namespace::clean is in use
Date: Sat, 3 May 2014 08:23:37 +0000
To: Victor Efimov via RT <bug-namespace-clean [...] rt.cpan.org>
From: Peter Rabbitson <ribasushi [...] cpan.org>
On Fri, May 02, 2014 at 06:21:04PM -0400, Victor Efimov via RT wrote: Show quoted text
> Fri May 02 18:21:03 2014: Request 95298 was acted upon. > Transaction: Ticket created by vsespb > Queue: namespace-clean > Subject: cannot redefine subroutine by symbolic ref when namespace::clean > is in use > Broken in: 0.25 > Severity: Normal > Owner: Nobody > Requestors: victor@vsespb.ru > Status: new > Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=95298 > >
If we swap I.pm with Carp.pm, change 'mysub' with 'carp', and (roughly) recreate the namespace::clean functionality, your example looks like this one-liner: perl -e ' use warnings; use strict; no warnings "redefine"; no strict "refs"; BEGIN { require Carp; *{"carp"} = \&Carp::carp } carp("Foo"); *{"carp"} = sub { warn "not the carp you are looking for" }; carp("Bar"); BEGIN { delete ${*main::}{carp} } ' Note the sequence of events: 0) the carp stash slot is created 1) the parsing of both carp(...) calls (not their execution) 2) the stash-slot is deleted 3) the first carp() is called 4) the stash gets a new member reintroduced 5) the second carp() is called After steps 0 and 1 both the resulting optree entries AND *{${*main::}{carp}}{CODE} are "aliases" to the same GlobSlot. This is why in your non-n::c code you can change *{"carp"} and see the changes reflected in the optree. However in the above case at step 2 this aliasing is lost for good, and you are seeing the effect you are seeing. I don't think there is much namespace::clean can do to make this easier for your use case. I will keep this ticket open for another week to facilitate further discussion (if any). Feel free to close this ticket earlier if there isn't much to add. Cheers
Closing after no further reply from OP
On Tue May 20 17:22:39 2014, RIBASUSHI wrote: Show quoted text
> Closing after no further reply from OP
Oh, yes! Thank you for explanation. I've read it. I don't have idea how this can be improved. So probably wontfix.