Subject: | mouse.t failure on 5.8.8: scrubbing symbols that it shouldn't be |
Hello,
The test output that includes prereq versions is attached separately as it is a bit big.
I've had few of the Mouse tests fail on perl 5.8.8 because namespace::autoclean is scrubbing symbols that it shouldn't be. This is against the current Mouse (2.4.1).
t/mouse.t .................. 1/?
# Failed test 'Consuming::Class::InBegin::guff added via glob assignment'
# at t/mouse.t line 153.
# Failed test 'Consuming::Class::InBegin::CAT constant'
# at t/mouse.t line 169.
# Looks like you failed 2 tests of 40.
It scrubs `use constant XYZ`'s and methods added via a glob that are added to a Mouse class via a role. Pretty sure it is limited to perl 5.8's and older.
To reproduce on 5.8.8:
1. Some::Role defines a constant with `use constant`.
2. Some::Role is applied to the first Mouse class and the constant is not cleaned from the package.
3. Then Some::Role is applied using a BEGIN block to the second Mouse class. The constant is incorrectly (IMO) scrubbed from the second class.
I have stuck a stripped down version of the failing test case at https://gist.github.com/andyjones/b3eb7f6dca5c216ddf6e
The constant is only scrubbed when the role has already been applied to a different class *and* it is being applied with a BEGIN block (ie. first the role is applied and then namespace::autoclean runs removing the constant).
It works correctly when you remove the BEGIN block (namespace::autoclean runs first, then the role is applied copying the constant across).
Also, it only affects classes after the role has been applied to at least one other class already.
I've tried to debug it but got lost down the rabbit hole. Sub::Identify correctly says the code ref for the constant belongs to the role when it scrubs the role.
When the role is applied to the first class, Sub::Identify says the code ref for the constant belongs to the first class.
When the role is applied to the second class, Sub::Identify still says the code ref for the constant belongs to the first class so it scrubs it. I'm not sure why the code ref belongs to the first class rather than the second class (or even the role) - I'm guessing there is an optimisation happening but I don't understand it.
I think the failing test case when methods are added via glob assignments has the same cause.
I'm not sure how to address this.
One option is to go back to Mouse's metaclass. This prevents symbols from Mouse::Roles etc being scrubbed. But as Graham points out in RT#96441, the Mouse metaclass isn't reliable so it is at the expense that some imported functions aren't scrubbed:
{
package Some::Class;
use File::Basename 'fileparse';
use Mouse;
};
Some::Class->meta->get_method_list # returns ['meta', 'fileparse']
There are also many Mouse tests that are already disabled under 5.8.8 so maybe it is fair enough to disable a couple more and document that Mouse compatibility is iffy under 5.8?
Happy to supply code/docs if you want
Subject: | output.txt |
$> cpanm -v namespace::autoclean
cpanm (App::cpanminus) 1.7001 on perl 5.008008 built for x86_64-linux-thread-multi
Work directory is /root/.cpanm/work/1422534323.7478
You have make /usr/bin/make
You have LWP 5.837
You have /bin/tar: tar (GNU tar) 1.15.1
You have /usr/bin/unzip
Searching namespace::autoclean on cpanmetadb ...
--> Working on namespace::autoclean
Fetching http://www.cpan.org/authors/id/E/ET/ETHER/namespace-autoclean-0.24.tar.gz ... OK
... output snipped ...
t/00-report-prereqs.t ...... #
# Versions for all modules listed in MYMETA.json (including optional ones):
#
# === Configure Requires ===
#
# Module Want Have
# ------------------- ----- -----
# Module::Build::Tiny 0.039 0.039
#
# === Test Requires ===
#
# Module Want Have
# ------------------- ---- --------
# Carp any 1.3301
# ExtUtils::MakeMaker any 7.04
# File::Basename any 2.74
# File::Spec any 3.47
# Scalar::Util any 1.41
# Test::More 0.88 1.001014
# Test::Requires any 0.06
# base any 2.07
# constant any 1.05
# overload any 1.04
#
# === Test Recommends ===
#
# Module Want Have
# ---------- -------- --------
# CPAN::Meta 2.120900 2.143240
#
# === Runtime Requires ===
#
# Module Want Have
# -------------------- ---- ----
# B::Hooks::EndOfScope 0.12 0.12
# List::Util any 1.41
# Sub::Identify any 0.10
# namespace::clean 0.20 0.25
# strict any 1.03
# warnings any 1.05
#
# === Other Modules ===
#
# Module Want Have
# ----------------------------- ---- --------
# Class::MOP any 2.1403
# Moo any 1.005000
# Moose any 2.1403
# MooseX::Role::WithOverloading any missing
# Mouse any 2.4.1
# Mouse::PurePerl any undef
# Sub::Install any 0.925
# Sub::Name any 0.05
#
... output snipped ...
t/mouse-pp.t ............... ok
t/mouse.t .................. 1/?
# Failed test 'Consuming::Class::InBegin::guff added via glob assignment'
# at t/mouse.t line 153.
# Failed test 'Consuming::Class::InBegin::CAT constant'
# at t/mouse.t line 169.
# Looks like you failed 2 tests of 40.
t/mouse.t .................. Dubious, test returned 2 (wstat 512, 0x200)
Failed 2/40 subtests
(5 TODO tests unexpectedly succeeded)
t/overload.t ............... ok
t/sub-install.t ............ ok
t/sub-name.t ............... ok
Test Summary Report
-------------------
t/mouse.t (Wstat: 512 Tests: 40 Failed: 2)
Failed tests: 33, 39
TODO passed: 1, 6, 11, 21, 31
Non-zero exit status: 2