On Tue Jan 31 10:02:21 2012, ETHER wrote:
Show quoted text> It appears that Class::Method::Modifiers isn't marking its methods as
> methods, such that namespace::(auto)?clean recognizes them as such:
Ok, this code helps clarify the problem: CMM modifies a sub in such a
way that
n::c now thinks that it is an uncleaned import.
use strict;
use warnings;
use Test::More;
use Class::MOP;
use Data::Dumper;
use Test::CleanNamespaces;
sub symbols
{
my $ns = shift;
my $meta = Class::MOP::class_of($ns) ||
Class::MOP::Class->initialize($ns);
my %methods = map { ($_ => 1) } $meta->get_method_list;
my @symbols = keys %{ $meta->get_all_package_symbols('CODE') ||
{} };
}
sub imports
{
my $ns = shift;
my $meta = Class::MOP::class_of($ns) ||
Class::MOP::Class->initialize($ns);
my %methods = map { ($_ => 1) } $meta->get_method_list;
my @symbols = keys %{ $meta->get_all_package_symbols('CODE') ||
{} };
my @imports = grep { !$methods{$_} } @symbols;
}
BEGIN {
package Foo;
sub foo { print "normal Foo::foo sub\n"; }
}
BEGIN {
print "### Foo symbols initially: ", Dumper([ symbols('Foo') ]);
print "### Foo imports initially: ", Dumper([ imports('Foo') ]);
namespaces_clean('Foo');
}
BEGIN {
package Foo;
use Class::Method::Modifiers;
print "### redefining foo\n";
around foo => sub { print "wrapped foo sub\n" };
}
print "### Foo symbols after modification: ", Dumper([
symbols('Foo') ]);
print "### Foo imports after modification: ", Dumper([
imports('Foo') ]);
namespaces_clean('Foo');
done_testing;
__END__
### Foo symbols initially: $VAR1 = [
'foo'
];
### Foo imports initially: $VAR1 = [];
ok 1 - Foo contains no imported functions
### redefining foo
### Foo symbols after modification: $VAR1 = [
'after',
'around',
'foo',
'before'
];
### Foo imports after modification: $VAR1 = [
'after',
'around',
'foo',
'before'
];
not ok 2 - Foo contains no imported functions
# Failed test 'Foo contains no imported functions'
# at external_clean.pl line 45.
# remaining imports: [
# 'after',
# 'around',
# 'foo',
# 'before'
# ]
1..2
# Looks like you failed 1 test of 2.
Further, once CMM tampers with 'foo', it also is showing up as an
import, when
initially it did not.
Using namespace::autoclean inside the second 'package Foo' declaration does
clean the begin/around/after subs, but it does not clean 'foo'; it does not
seem possible to use namespace::clean anywhere, as no matter where it is
placed, CMM reports the error "The method 'foo' is not found in the
inheritance hierarchy for class Foo".