Subject: | Using Module::Pluggable is problematic (needs to allow 'execpt' regex to avoid SCCS files when in source control context |
Date: | Tue, 11 May 2010 14:26:18 -0400 |
To: | bug-Perl-Critic [...] rt.cpan.org |
From: | Darren Ball <balldarrens [...] gmail.com> |
An example of the situation:
Warning: Use of "CORE" without parentheses is ambiguous at (eval 62) line 1.
Couldn't require
Perl::Critic::Policy::BuiltinFunctions::SCCS::s.ProhibitBooleanGrep :
Bareword "ProhibitBooleanGrep" not allowed while "strict subs" in use at
(eval 62) line 1.
at /opt/langs/ActivePerl-5.10.1/lib/Module/Pluggable.pm line 28
Warning: Use of "CORE" without parentheses is ambiguous at (eval 63) line 1.
Couldn't require
Perl::Critic::Policy::BuiltinFunctions::SCCS::s.ProhibitComplexMappings :
Bareword "ProhibitComplexMappings" not allowed while "strict subs" in use at
(eval 63) line 1.
at /opt/langs/ActivePerl-5.10.1/lib/Module/Pluggable.pm line 28
Warning: Use of "CORE" without parentheses is ambiguous at (eval 64) line 1.
Couldn't require
Perl::Critic::Policy::BuiltinFunctions::SCCS::s.ProhibitLvalueSubstr :
Bareword "ProhibitLvalueSubstr" not allowed while "strict subs" in use at
(eval 64) line 1.
at /opt/langs/ActivePerl-5.10.1/lib/Module/Pluggable.pm line 28
Warning: Use of "CORE" without parentheses is ambiguous at (eval 65) line 1.
...
In Perl::Critic::PolicyFactory, you are using Module::Pluggable, and the
namespace search path that you are providing seems to be scanning all
directory structures, even source control directories.
This needs to be adjusted so that an exclusion regex can be 'passed' to the
import (not sure why this is in import) method.
The old code looks like:
sub import {
my ( $class, %args ) = @_;
my $test_mode = $args{-test};
my $extra_test_policies = $args{'-extra-test-policies'};
if ( not @site_policy_names ) {
my $eval_worked = eval {
require Module::Pluggable;
print $POLICY_NAMESPACE;
Module::Pluggable->import(search_path => $POLICY_NAMESPACE,
require => 1, inner => 0);
@site_policy_names = plugins(); #Exported by Module::Pluggable
1;
};
if (not $eval_worked) {
if ( $EVAL_ERROR ) {
throw_generic
qq<Can't load Policies from namespace
"$POLICY_NAMESPACE": $EVAL_ERROR>;
}
throw_generic
qq<Can't load Policies from namespace "$POLICY_NAMESPACE"
for an unknown reason.>;
}
if ( not @site_policy_names ) {
throw_generic
qq<No Policies found in namespace "$POLICY_NAMESPACE".>;
}
}
# In test mode, only load native policies, not third-party ones
if ( $test_mode && any {m/\b blib \b/xms} @INC ) {
@site_policy_names = _modules_from_blib( @site_policy_names );
if ($extra_test_policies) {
my @extra_policy_full_names =
map { "${POLICY_NAMESPACE}::$_" } @{$extra_test_policies};
push @site_policy_names, @extra_policy_full_names;
}
}
return 1;
}
New code that is working to avoid errors above (excluding SCCS directories
using the 'except' parameter for Module::Pluggable):
sub import {
my ( $class, %args ) = @_;
my $test_mode = $args{-test};
my $extra_test_policies = $args{'-extra-test-policies'};
if ( not @site_policy_names ) {
my $eval_worked = eval {
require Module::Pluggable;
print $POLICY_NAMESPACE;
Module::Pluggable->import(search_path => $POLICY_NAMESPACE,
require => 1, inner => 0,
except => qr /::SCCS::/);
@site_policy_names = plugins(); #Exported by Module::Pluggable
1;
};
if (not $eval_worked) {
if ( $EVAL_ERROR ) {
throw_generic
qq<Can't load Policies from namespace
"$POLICY_NAMESPACE": $EVAL_ERROR>;
}
throw_generic
qq<Can't load Policies from namespace "$POLICY_NAMESPACE"
for an unknown reason.>;
}
if ( not @site_policy_names ) {
throw_generic
qq<No Policies found in namespace "$POLICY_NAMESPACE".>;
}
}
# In test mode, only load native policies, not third-party ones
if ( $test_mode && any {m/\b blib \b/xms} @INC ) {
@site_policy_names = _modules_from_blib( @site_policy_names );
if ($extra_test_policies) {
my @extra_policy_full_names =
map { "${POLICY_NAMESPACE}::$_" } @{$extra_test_policies};
push @site_policy_names, @extra_policy_full_names;
}
}
return 1;
}
There should be a way to pass through any argument that is potentially
usable for Module::Pluggable to this factory.