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