File Coverage

blib/lib/Perl/Critic/Policy/Community/DiscouragedModules.pm
Criterion Covered Total %
statement 22 23 95.6
branch 2 2 100.0
condition 6 9 66.6
subroutine 9 10 90.0
pod 4 5 80.0
total 43 49 87.7


line stmt bran cond sub pod time code
1             package Perl::Critic::Policy::Community::DiscouragedModules;
2              
3 1     1   495 use strict;
  1         2  
  1         32  
4 1     1   5 use warnings;
  1         3  
  1         30  
5              
6 1     1   6 use Perl::Critic::Utils qw(:severities :classification :ppi);
  1         2  
  1         77  
7 1     1   432 use parent 'Perl::Critic::Policy';
  1         3  
  1         7  
8              
9             our $VERSION = 'v1.0.1';
10              
11             sub supported_parameters {
12             (
13             {
14 4     4 0 22554 name => 'allowed_modules',
15             description => 'Modules that you want to allow, despite being discouraged.',
16             behavior => 'string list',
17             },
18             )
19             }
20 18     18 1 176 sub default_severity { $SEVERITY_HIGH }
21 0     0 1 0 sub default_themes { 'community' }
22 4     4 1 76531 sub applies_to { 'PPI::Statement::Include' }
23              
24             my %modules = (
25             'AnyEvent' => 'AnyEvent\'s author refuses to use public bugtracking and actively breaks interoperability. POE, IO::Async, and Mojo::IOLoop are widely used and interoperable async event loops.',
26             'Any::Moose' => 'Any::Moose is deprecated. Use Moo instead.',
27             'Class::DBI' => 'Class::DBI is an ancient database ORM abstraction layer which is buggy and abandoned. See DBIx::Class for a more modern DBI-based ORM, or Mad::Mapper for a Mojolicious-style ORM.',
28             'CGI' => 'CGI.pm is an ancient module for communicating via the CGI protocol, with tons of bad practices and cruft. Use a modern framework such as those based on Plack (Web::Simple, Dancer2, Catalyst) or Mojolicious, they can still be served via CGI if you choose. Use CGI::Tiny if you are limited to the CGI protocol.',
29             'Coro' => 'Coro abuses Perl internals in an unsupported way. Consider Future and Future::AsyncAwait in combination with event loops for similar semantics.',
30             'Error' => 'Error.pm is overly magical and discouraged by its maintainers. Try Throwable for exception classes in Moo/Moose, or Exception::Class otherwise. Try::Tiny or Syntax::Keyword::Try are recommended for the try/catch syntax.',
31             'File::Slurp' => 'File::Slurp gets file encodings all wrong, line endings on win32 are messed up, and it was written before layers were properly added. Use File::Slurper, Path::Tiny, Data::Munge, or Mojo::File.',
32             'FindBin' => 'FindBin depends on the sometimes vague definition of "initial script" and can\'t be updated to fix bugs in old Perls. Use Path::This or lib::relative to work with the absolute path of the current source file instead.',
33             'HTML::Template' => 'HTML::Template is an old and buggy module, try Template Toolkit, Mojo::Template, or Text::Xslate instead, or HTML::Template::Pro if you must use the same syntax.',
34             'IO::Socket::INET6' => 'IO::Socket::INET6 is an old attempt at an IPv6 compatible version of IO::Socket::INET, but has numerous issues and is discouraged by the maintainer in favor of IO::Socket::IP, which transparently creates IPv4 and IPv6 sockets.',
35             'JSON::Any' => 'JSON::Any is deprecated. Use JSON::MaybeXS instead.',
36             'JSON::XS' => 'JSON::XS\'s author refuses to use public bugtracking and actively breaks interoperability. Cpanel::JSON::XS is a fork with several bugfixes and a more collaborative maintainer. See also JSON::MaybeXS.',
37             'Net::IRC' => 'Net::IRC is an ancient module implementing the IRC protocol. Use a modern event-loop-based module instead. Choices are POE::Component::IRC (and Bot::BasicBot based on that), Net::Async::IRC, and Mojo::IRC.',
38             'Switch' => 'Switch.pm is a buggy and outdated source filter which can cause any number of strange errors, in addition to the problems with smart-matching shared by its replacement, the \'switch\' feature (given/when). Try Switch::Plain or Syntax::Keyword::Match instead.',
39             'XML::Simple' => 'XML::Simple tries to coerce complex XML documents into perl data structures. This leads to overcomplicated structures and unexpected behavior. Use a proper DOM parser instead like XML::LibXML, XML::TreeBuilder, XML::Twig, or Mojo::DOM.',
40             );
41              
42             sub _violation {
43 18     18   384 my ($self, $module, $elem) = @_;
44 18         53 my $desc = "Used module $module";
45 18   33     55 my $expl = $modules{$module} // "Module $module is discouraged.";
46 18         82 return $self->violation($desc, $expl, $elem);
47             }
48              
49             sub violates {
50 58     58 1 5087 my ($self, $elem) = @_;
51 58 100 66     145 return () unless defined $elem->module and exists $modules{$elem->module} and not exists $self->{_allowed_modules}{$elem->module};
      100        
52 18         1251 return $self->_violation($elem->module, $elem);
53             }
54              
55             1;
56              
57             =head1 NAME
58              
59             Perl::Critic::Policy::Community::DiscouragedModules - Various modules
60             discouraged from use
61              
62             =head1 DESCRIPTION
63              
64             Various modules are discouraged by some subsets of the community, for various
65             reasons which may include: buggy behavior, cruft, performance problems,
66             maintainer issues, or simply better modern replacements. This is a high
67             severity complement to
68             L<Perl::Critic::Policy::Community::PreferredAlternatives>.
69              
70             =head1 MODULES
71              
72             =head2 AnyEvent
73              
74             L<AnyEvent>'s author refuses to use public bugtracking and actively breaks
75             interoperability. L<POE>, L<IO::Async>, and L<Mojo::IOLoop> are widely used and
76             interoperable async event loops.
77              
78             =head2 Any::Moose
79              
80             L<Any::Moose> is deprecated. Use L<Moo> instead.
81              
82             =head2 Class::DBI
83              
84             L<Class::DBI> is an ancient database L<ORM|https://en.wikipedia.org/wiki/Object-relational_mapping>
85             abstraction layer which is buggy and abandoned. See L<DBIx::Class> for a more
86             modern L<DBI>-based ORM, or L<Mad::Mapper> for a L<Mojolicious>-style ORM.
87              
88             =head2 CGI
89              
90             L<CGI>.pm is an ancient module for communicating via the CGI protocol, with
91             tons of bad practices and cruft. Use a modern framework such as those based on
92             L<Plack> (L<Web::Simple>, L<Dancer2>, L<Catalyst>) or L<Mojolicious>, they can
93             still be served via CGI if you choose. Use L<CGI::Tiny> if you are limited to
94             the CGI protocol.
95              
96             =head2 Coro
97              
98             L<Coro> abuses Perl internals in an unsupported way. Consider L<Future> and
99             L<Future::AsyncAwait> in combination with event loops for similar semantics.
100              
101             =head2 Error
102              
103             L<Error>.pm is overly magical and discouraged by its maintainers. Try
104             L<Throwable> for exception classes in L<Moo>/L<Moose>, or L<Exception::Class>
105             otherwise. L<Try::Tiny> or L<Syntax::Keyword::Try> are recommended for the
106             C<try>/C<catch> syntax.
107              
108             =head2 FindBin
109              
110             L<FindBin> is often used to retrieve the absolute path to the directory
111             containing the initially executed script, a mechanism which is not always
112             logically clear. Additionally, it has serious bugs on old Perls and can't be
113             updated from CPAN to fix them. The L<Path::This> module provides similar
114             variables and constants based on the absolute path to the current source file.
115             The L<lib::relative> module resolves passed relative paths to the current
116             source file for the common case of adding local module include directories.
117             Each of these documents examples of achieving the same behavior with core
118             modules.
119              
120             =head2 File::Slurp
121              
122             L<File::Slurp> gets file encodings all wrong, line endings on win32 are messed
123             up, and it was written before layers were properly added. Use L<File::Slurper>,
124             L<Path::Tiny/"slurp">, L<Data::Munge/"slurp">, or L<Mojo::File/"slurp">.
125              
126             =head2 HTML::Template
127              
128             L<HTML::Template> is an old and buggy module, try L<Template::Toolkit>,
129             L<Mojo::Template>, or L<Text::Xslate> instead, or L<HTML::Template::Pro> if you
130             must use the same syntax.
131              
132             =head2 IO::Socket::INET6
133              
134             L<IO::Socket::INET6> is an old attempt at an IPv6 compatible version of
135             L<IO::Socket::INET>, but has numerous issues and is discouraged by the
136             maintainer in favor of L<IO::Socket::IP>, which transparently creates IPv4 and
137             IPv6 sockets.
138              
139             =head2 JSON::Any
140              
141             L<JSON::Any> is deprecated. Use L<JSON::MaybeXS> instead.
142              
143             =head2 JSON::XS
144              
145             L<JSON::XS>'s author refuses to use public bugtracking and actively breaks
146             interoperability. L<Cpanel::JSON::XS> is a fork with several bugfixes and a
147             more collaborative maintainer. See also L<JSON::MaybeXS>.
148              
149             =head2 Net::IRC
150              
151             L<Net::IRC> is an ancient module implementing the IRC protocol. Use a modern
152             event-loop-based module instead. Choices are L<POE::Component::IRC> (used for
153             L<Bot::BasicBot>), L<Net::Async::IRC>, and L<Mojo::IRC>.
154              
155             =head2 Switch
156              
157             L<Switch>.pm is a buggy and outdated source filter which can cause any number
158             of strange errors, in addition to the problems with smart-matching shared by
159             its replacement, L<feature/"The 'switch' feature"> (C<given>/C<when>). Try
160             L<Switch::Plain> or L<Syntax::Keyword::Match> instead.
161              
162             =head2 XML::Simple
163              
164             L<XML::Simple> tries to coerce complex XML documents into perl data structures.
165             This leads to overcomplicated structures and unexpected behavior. Use a proper
166             DOM parser instead like L<XML::LibXML>, L<XML::TreeBuilder>, L<XML::Twig>, or
167             L<Mojo::DOM>.
168              
169             =head1 AFFILIATION
170              
171             This policy is part of L<Perl::Critic::Community>.
172              
173             =head1 CONFIGURATION
174              
175             Occasionally you may find yourself needing to use one of these discouraged
176             modules, and do not want the warnings. You can do so by putting something like
177             the following in a F<.perlcriticrc> file like this:
178              
179             [Community::DiscouragedModules]
180             allowed_modules = FindBin Any::Moose
181              
182             The same option is offered for L<Perl::Critic::Policy::Community::PreferredAlternatives>.
183              
184             =head1 AUTHOR
185              
186             Dan Book, C<dbook@cpan.org>
187              
188             =head1 COPYRIGHT AND LICENSE
189              
190             Copyright 2015, Dan Book.
191              
192             This library is free software; you may redistribute it and/or modify it under
193             the terms of the Artistic License version 2.0.
194              
195             =head1 SEE ALSO
196              
197             L<Perl::Critic>