File Coverage

blib/lib/Perl/Critic/Policy/Bangs/ProhibitRefProtoOrProto.pm
Criterion Covered Total %
statement 29 30 96.6
branch 9 14 64.2
condition 3 9 33.3
subroutine 8 9 88.8
pod 4 5 80.0
total 53 67 79.1


line stmt bran cond sub pod time code
1             package Perl::Critic::Policy::Bangs::ProhibitRefProtoOrProto;
2              
3 4     4   3476 use strict;
  4         9  
  4         122  
4 4     4   22 use warnings;
  4         8  
  4         92  
5 4     4   21 use Perl::Critic::Utils;
  4         7  
  4         69  
6 4     4   3634 use base 'Perl::Critic::Policy';
  4         8  
  4         1347  
7              
8             our $VERSION = '1.11_02';
9              
10 5     5 0 25097 sub supported_parameters { return () }
11 1     1 1 18 sub default_severity { return $SEVERITY_HIGH }
12 0     0 1 0 sub default_themes { return qw( bangs complexity ) }
13 2     2 1 35082 sub applies_to { return 'PPI::Token::Word' }
14              
15              
16             sub violates {
17 4     4 1 119 my ( $self, $elem, $doc ) = @_;
18              
19 4 100       50 return if $elem ne 'ref';
20 2 50       38 return if is_method_call($elem);
21 2 50       115 return if is_hash_key($elem);
22 2 50       174 return if is_subroutine_name($elem);
23              
24 2         113 my $suspectproto = $elem->snext_sibling();
25 2 50 33     58 if ( $suspectproto && $suspectproto->isa( 'PPI::Token::Symbol' ) ) {
26             # $suspectproto is the thing I'm calling ref on. Let's see if there's a || after that.
27 2 50 33     12 if ( $suspectproto->snext_sibling()
      33        
28             && $suspectproto->snext_sibling->isa( 'PPI::Token::Operator' )
29             && $suspectproto->snext_sibling() eq q{||} ) {
30 2         164 my $or = $suspectproto->snext_sibling;
31             # this is where I test to see if the thing after the || is the same as the thing before the ref
32 2 100       43 if ( $or->snext_sibling() eq $suspectproto->content() ) {
33             # here it looks like we have ref $proto || $proto
34 1         30 my $desc = q{"ref $proto || $proto" construct found}; ## no critic (RequireInterpolationOfMetachars)
35 1         2 my $expl = q{Probably cut-and-pasted example code};
36 1         11 return $self->violation( $desc, $expl, $elem );
37             }
38             }
39             }
40              
41 1         39 return;
42             }
43              
44             1;
45              
46             __END__
47             =head1 NAME
48              
49             Perl::Critic::Policy::Bangs::ProhibitRefProtoOrProto - Create a clone() method if you need copies of objects.
50              
51             =head1 AFFILIATION
52              
53             This Policy is part of the L<Perl::Critic::Bangs> distribution.
54              
55             =head1 DESCRIPTION
56              
57             Many times you'll see code for object constructors that's been
58             cut-and-pasted from somewhere else, and it looks like this:
59              
60             sub new {
61             my $proto = shift;
62             my $class = ref($proto) || $proto;
63             my $self = bless {}, $class;
64             ...
65             }
66              
67             The C<$class> is derived from the first parameter, whether it's the
68             class name, or an existing object. This lets you do this:
69              
70             my $fido = Dog->new();
71              
72             which is very common, and the less likely
73              
74             my $rover = $fido->new();
75              
76             Now, why would you want to instantiate an object based on the type
77             of another object? If you want to make C<$rover> a clone of C<$fido>,
78             then Dog should have a C<clone()> method, instead of overloading
79             the meaning of C<new()>.
80              
81             That's all the C<ref($proto) || $proto> does for you. If you don't
82             need that dubious functionality, then write your constructors like
83             this:
84              
85             sub new {
86             my $class = shift;
87             my $self = bless {}, $class;
88             }
89              
90             See also Randal Schwartz's take on it at
91             L<http://www.stonehenge.com/merlyn/UnixReview/col52.html>.
92              
93             =head1 CONFIGURATION
94              
95             This Policy is not configurable except for the standard options.
96              
97             =head1 AUTHOR
98              
99             Andrew Moore <amoore@mooresystems.com>
100              
101             =head1 ACKNOWLEDGMENTS
102              
103             Adapted from policies by Jeffrey Ryan Thalhammer <thaljef@cpan.org>,
104             and work done by Andrew Moore <amoore@mooresystems.com>.
105              
106             =head1 COPYRIGHT
107              
108             Copyright (C) 2006-2013 Andy Lester
109              
110             This library is free software; you can redistribute it and/or modify it
111             under the terms of the Artistic License 2.0.
112              
113             =cut