Class-Sniff
view release on metacpan or search on metacpan
lib/Class/Sniff.pm view on Meta::CPAN
sub inc {
my ( $self, $value ) = @_;
return $value + 1;
}
sub increment {
my ( $proto, $number ) = @_;
return $number + 1;
}
However, this will not match the above methods:
sub increment {
my ( $proto, $number ) = @_;
return 1 + $number;
}
=head3 Code Smell: duplicate methods
This is frequently a sign of "cut and paste" code. The duplication should be
removed. You may feel OK with this if the duplicated methods are exported
"helper" subroutines such as "Carp::croak".
=cut
sub duplicate_methods {
my $self = shift;
my @duplicates;
foreach my $methods ( values %{ $self->{duplicates} } ) {
if ( @$methods > 1 ) {
push @duplicates => $methods;
}
}
return @duplicates;
}
=head2 C<long_methods> (highly experimental)
my $num_long_methods = $sniff->long_methods;
my %long_methods = $sniff->long_methods;
Returns methods longer than C<method_length>.
This value defaults to 50 (lines) and
can be overridden in the constructor (but not later).
=over 4
=item * How to count the length of a method.
my $start_line = B::svref_2object($coderef)->START->line;
my $end_line = B::svref_2object($coderef)->GV->LINE;
my $method_length = $end_line - $start_line;
The C<$start_line> returns the line number of the I<first expression> in the
subroutine, not the C<sub foo { ...> declaration. The subroutine's
declaration actually ends at the ending curly brace, so the following method
would be considered 3 lines long, even though you might count it differently:
sub new {
# this is our constructor
my ( $class, $arg_for ) = @_;
my $self = bless {} => $class;
return $self;
}
=cut
sub long_methods { %{ $_[0]->{long_methods} } }
=item * Exported methods
These are simply ignored because the C<B> modules think they start and end in
different packages.
=item * Where does it really start?
If you've taken a reference to a method I<prior> to the declaration of the
reference being seen, Perl might report a negative length or simply blow up.
We trap that for you and you'll never see those.
=back
Let me know how it works out :)
=head3 Code Smell: long methods
Note that long methods may not be a code smell at all. The research in the
topic suggests that methods longer than many experienced programmers are
comfortable with are, nonetheless, easy to write, understand, and maintain.
Take this with a grain of salt. See the book "Code Complete 2" by Microsoft
Press for more information on the research. That being said ...
Long methods might be doing too much and should be broken down into smaller
methods. They're harder to follow, harder to debug, and if they're doing more
than one thing, you might find that you need that functionality elsewhere, but
now it's tightly coupled to the long method's behavior. As always, use your
judgment.
=head2 C<parents>
# defaults to 'target_class'
my $num_parents = $sniff->parents;
my @parents = $sniff->parents;
my $num_parents = $sniff->parents('Some::Class');
my @parents = $sniff->parents('Some::Class');
In scalar context, lists the number of parents a class has.
In list context, lists the parents a class has.
=head3 Code Smell: multiple parens (multiple inheritance)
If a class has more than one parent, you may have unreachable or conflicting
methods.
=cut
sub parents {
my ( $self, $class ) = @_;
$class ||= $self->target_class;
unless ( exists $self->{classes}{$class} ) {
( run in 1.956 second using v1.01-cache-2.11-cpan-f56aa216473 )