Showing 64 of 64 total issues
Class has too many lines. [108/100] Open
class User
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::Slug
- Read upRead up
- Exclude checks
This cop checks if the length a class exceeds some maximum value. Comment lines can optionally be ignored. The maximum allowed length is configurable.
You can set literals you want to fold with CountAsOne
.
Available are: 'array', 'hash', and 'heredoc'. Each literal
will be counted as one line regardless of its actual size.
Example: CountAsOne: ['array', 'heredoc']
class Foo
ARRAY = [ # +1
1,
2
]
HASH = { # +3
key: 'value'
}
MSG = <<~HEREDOC # +1
Heredoc
content.
HEREDOC
end # 5 points
NOTE: This cop also applies for Struct
definitions.
Class has too many lines. [107/100] Open
class Event
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::Slug
include Geocoder::Model::Mongoid
- Read upRead up
- Exclude checks
This cop checks if the length a class exceeds some maximum value. Comment lines can optionally be ignored. The maximum allowed length is configurable.
You can set literals you want to fold with CountAsOne
.
Available are: 'array', 'hash', and 'heredoc'. Each literal
will be counted as one line regardless of its actual size.
Example: CountAsOne: ['array', 'heredoc']
class Foo
ARRAY = [ # +1
1,
2
]
HASH = { # +3
key: 'value'
}
MSG = <<~HEREDOC # +1
Heredoc
content.
HEREDOC
end # 5 points
NOTE: This cop also applies for Struct
definitions.
Similar blocks of code found in 2 locations. Consider refactoring. Open
def index
query = TalkQuery.new.select(current_user, params[:search], params[:my]).to_a
@pagy, @records = pagy(query, count: query.count)
respond_to do |format|
- Read upRead up
Duplicated Code
Duplicated code can lead to software that is hard to understand and difficult to change. The Don't Repeat Yourself (DRY) principle states:
Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.
When you violate DRY, bugs and maintenance problems are sure to follow. Duplicated code has a tendency to both continue to replicate and also to diverge (leaving bugs as two similar implementations differ in subtle ways).
Tuning
This issue has a mass of 43.
We set useful threshold defaults for the languages we support but you may want to adjust these settings based on your project guidelines.
The threshold configuration represents the minimum mass a code block must have to be analyzed for duplication. The lower the threshold, the more fine-grained the comparison.
If the engine is too easily reporting duplication, try raising the threshold. If you suspect that the engine isn't catching enough duplication, try lowering the threshold. The best setting tends to differ from language to language.
See codeclimate-duplication
's documentation for more information about tuning the mass threshold in your .codeclimate.yml
.
Refactorings
- Extract Method
- Extract Class
- Form Template Method
- Introduce Null Object
- Pull Up Method
- Pull Up Field
- Substitute Algorithm
Further Reading
- Don't Repeat Yourself on the C2 Wiki
- Duplicated Code on SourceMaking
- Refactoring: Improving the Design of Existing Code by Martin Fowler. Duplicated Code, p76
Similar blocks of code found in 2 locations. Consider refactoring. Open
def index
query = EventQuery.new.select(current_user, params[:search], params[:my]).to_a
@pagy, @records = pagy(query, count: query.count)
respond_to do |format|
- Read upRead up
Duplicated Code
Duplicated code can lead to software that is hard to understand and difficult to change. The Don't Repeat Yourself (DRY) principle states:
Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.
When you violate DRY, bugs and maintenance problems are sure to follow. Duplicated code has a tendency to both continue to replicate and also to diverge (leaving bugs as two similar implementations differ in subtle ways).
Tuning
This issue has a mass of 43.
We set useful threshold defaults for the languages we support but you may want to adjust these settings based on your project guidelines.
The threshold configuration represents the minimum mass a code block must have to be analyzed for duplication. The lower the threshold, the more fine-grained the comparison.
If the engine is too easily reporting duplication, try raising the threshold. If you suspect that the engine isn't catching enough duplication, try lowering the threshold. The best setting tends to differ from language to language.
See codeclimate-duplication
's documentation for more information about tuning the mass threshold in your .codeclimate.yml
.
Refactorings
- Extract Method
- Extract Class
- Form Template Method
- Introduce Null Object
- Pull Up Method
- Pull Up Field
- Substitute Algorithm
Further Reading
- Don't Repeat Yourself on the C2 Wiki
- Duplicated Code on SourceMaking
- Refactoring: Improving the Design of Existing Code by Martin Fowler. Duplicated Code, p76
CommentsController#create has approx 6 statements Open
def create
- Read upRead up
- Exclude checks
A method with Too Many Statements
is any method that has a large number of lines.
Too Many Statements
warns about any method that has more than 5 statements. Reek's smell detector for Too Many Statements
counts +1 for every simple statement in a method and +1 for every statement within a control structure (if
, else
, case
, when
, for
, while
, until
, begin
, rescue
) but it doesn't count the control structure itself.
So the following method would score +6 in Reek's statement-counting algorithm:
def parse(arg, argv, &error)
if !(val = arg) and (argv.empty? or /\A-/ =~ (val = argv[0]))
return nil, block, nil # +1
end
opt = (val = parse_arg(val, &error))[1] # +2
val = conv_arg(*val) # +3
if opt and !arg
argv.shift # +4
else
val[0] = nil # +5
end
val # +6
end
(You might argue that the two assigments within the first @if@ should count as statements, and that perhaps the nested assignment should count as +2.)
RankingController#index has approx 8 statements Open
def index
- Read upRead up
- Exclude checks
A method with Too Many Statements
is any method that has a large number of lines.
Too Many Statements
warns about any method that has more than 5 statements. Reek's smell detector for Too Many Statements
counts +1 for every simple statement in a method and +1 for every statement within a control structure (if
, else
, case
, when
, for
, while
, until
, begin
, rescue
) but it doesn't count the control structure itself.
So the following method would score +6 in Reek's statement-counting algorithm:
def parse(arg, argv, &error)
if !(val = arg) and (argv.empty? or /\A-/ =~ (val = argv[0]))
return nil, block, nil # +1
end
opt = (val = parse_arg(val, &error))[1] # +2
val = conv_arg(*val) # +3
if opt and !arg
argv.shift # +4
else
val[0] = nil # +5
end
val # +6
end
(You might argue that the two assigments within the first @if@ should count as statements, and that perhaps the nested assignment should count as +2.)
TalksController#show has approx 7 statements Open
def show
- Read upRead up
- Exclude checks
A method with Too Many Statements
is any method that has a large number of lines.
Too Many Statements
warns about any method that has more than 5 statements. Reek's smell detector for Too Many Statements
counts +1 for every simple statement in a method and +1 for every statement within a control structure (if
, else
, case
, when
, for
, while
, until
, begin
, rescue
) but it doesn't count the control structure itself.
So the following method would score +6 in Reek's statement-counting algorithm:
def parse(arg, argv, &error)
if !(val = arg) and (argv.empty? or /\A-/ =~ (val = argv[0]))
return nil, block, nil # +1
end
opt = (val = parse_arg(val, &error))[1] # +2
val = conv_arg(*val) # +3
if opt and !arg
argv.shift # +4
else
val[0] = nil # +5
end
val # +6
end
(You might argue that the two assigments within the first @if@ should count as statements, and that perhaps the nested assignment should count as +2.)
UsersDecorator has at least 5 instance variables Open
class UsersDecorator
- Read upRead up
- Exclude checks
Too Many Instance Variables
is a special case of LargeClass
.
Example
Given this configuration
TooManyInstanceVariables:
max_instance_variables: 3
and this code:
class TooManyInstanceVariables
def initialize
@arg_1 = :dummy
@arg_2 = :dummy
@arg_3 = :dummy
@arg_4 = :dummy
end
end
Reek would emit the following warning:
test.rb -- 5 warnings:
[1]:TooManyInstanceVariables has at least 4 instance variables (TooManyInstanceVariables)
UsersController has at least 7 instance variables Open
class UsersController < ApplicationController
- Read upRead up
- Exclude checks
Too Many Instance Variables
is a special case of LargeClass
.
Example
Given this configuration
TooManyInstanceVariables:
max_instance_variables: 3
and this code:
class TooManyInstanceVariables
def initialize
@arg_1 = :dummy
@arg_2 = :dummy
@arg_3 = :dummy
@arg_4 = :dummy
end
end
Reek would emit the following warning:
test.rb -- 5 warnings:
[1]:TooManyInstanceVariables has at least 4 instance variables (TooManyInstanceVariables)
EventPresenter has at least 13 instance variables Open
class EventPresenter
- Read upRead up
- Exclude checks
Too Many Instance Variables
is a special case of LargeClass
.
Example
Given this configuration
TooManyInstanceVariables:
max_instance_variables: 3
and this code:
class TooManyInstanceVariables
def initialize
@arg_1 = :dummy
@arg_2 = :dummy
@arg_3 = :dummy
@arg_4 = :dummy
end
end
Reek would emit the following warning:
test.rb -- 5 warnings:
[1]:TooManyInstanceVariables has at least 4 instance variables (TooManyInstanceVariables)
TalksController has at least 9 instance variables Open
class TalksController < ApplicationController
- Read upRead up
- Exclude checks
Too Many Instance Variables
is a special case of LargeClass
.
Example
Given this configuration
TooManyInstanceVariables:
max_instance_variables: 3
and this code:
class TooManyInstanceVariables
def initialize
@arg_1 = :dummy
@arg_2 = :dummy
@arg_3 = :dummy
@arg_4 = :dummy
end
end
Reek would emit the following warning:
test.rb -- 5 warnings:
[1]:TooManyInstanceVariables has at least 4 instance variables (TooManyInstanceVariables)
EventPresenter#add_in_grid has approx 6 statements Open
def add_in_grid(dates, schedules)
- Read upRead up
- Exclude checks
A method with Too Many Statements
is any method that has a large number of lines.
Too Many Statements
warns about any method that has more than 5 statements. Reek's smell detector for Too Many Statements
counts +1 for every simple statement in a method and +1 for every statement within a control structure (if
, else
, case
, when
, for
, while
, until
, begin
, rescue
) but it doesn't count the control structure itself.
So the following method would score +6 in Reek's statement-counting algorithm:
def parse(arg, argv, &error)
if !(val = arg) and (argv.empty? or /\A-/ =~ (val = argv[0]))
return nil, block, nil # +1
end
opt = (val = parse_arg(val, &error))[1] # +2
val = conv_arg(*val) # +3
if opt and !arg
argv.shift # +4
else
val[0] = nil # +5
end
val # +6
end
(You might argue that the two assigments within the first @if@ should count as statements, and that perhaps the nested assignment should count as +2.)
TalksController#index has approx 6 statements Open
def index
- Read upRead up
- Exclude checks
A method with Too Many Statements
is any method that has a large number of lines.
Too Many Statements
warns about any method that has more than 5 statements. Reek's smell detector for Too Many Statements
counts +1 for every simple statement in a method and +1 for every statement within a control structure (if
, else
, case
, when
, for
, while
, until
, begin
, rescue
) but it doesn't count the control structure itself.
So the following method would score +6 in Reek's statement-counting algorithm:
def parse(arg, argv, &error)
if !(val = arg) and (argv.empty? or /\A-/ =~ (val = argv[0]))
return nil, block, nil # +1
end
opt = (val = parse_arg(val, &error))[1] # +2
val = conv_arg(*val) # +3
if opt and !arg
argv.shift # +4
else
val[0] = nil # +5
end
val # +6
end
(You might argue that the two assigments within the first @if@ should count as statements, and that perhaps the nested assignment should count as +2.)
ExportSubscriber#self.export_csv contains iterators nested 2 deep Open
users.each do |user|
- Read upRead up
- Exclude checks
A Nested Iterator
occurs when a block contains another block.
Example
Given
class Duck
class << self
def duck_names
%i!tick trick track!.each do |surname|
%i!duck!.each do |last_name|
puts "full name is #{surname} #{last_name}"
end
end
end
end
end
Reek would report the following warning:
test.rb -- 1 warning:
[5]:Duck#duck_names contains iterators nested 2 deep (NestedIterators)
Gravatar has at least 8 instance variables Open
class Gravatar
- Read upRead up
- Exclude checks
Too Many Instance Variables
is a special case of LargeClass
.
Example
Given this configuration
TooManyInstanceVariables:
max_instance_variables: 3
and this code:
class TooManyInstanceVariables
def initialize
@arg_1 = :dummy
@arg_2 = :dummy
@arg_3 = :dummy
@arg_4 = :dummy
end
end
Reek would emit the following warning:
test.rb -- 5 warnings:
[1]:TooManyInstanceVariables has at least 4 instance variables (TooManyInstanceVariables)
ExportSubscriber#self.speakers contains iterators nested 2 deep Open
talk.users.each do |user|
- Read upRead up
- Exclude checks
A Nested Iterator
occurs when a block contains another block.
Example
Given
class Duck
class << self
def duck_names
%i!tick trick track!.each do |surname|
%i!duck!.each do |last_name|
puts "full name is #{surname} #{last_name}"
end
end
end
end
end
Reek would report the following warning:
test.rb -- 1 warning:
[5]:Duck#duck_names contains iterators nested 2 deep (NestedIterators)
EventsController#index has approx 6 statements Open
def index
- Read upRead up
- Exclude checks
A method with Too Many Statements
is any method that has a large number of lines.
Too Many Statements
warns about any method that has more than 5 statements. Reek's smell detector for Too Many Statements
counts +1 for every simple statement in a method and +1 for every statement within a control structure (if
, else
, case
, when
, for
, while
, until
, begin
, rescue
) but it doesn't count the control structure itself.
So the following method would score +6 in Reek's statement-counting algorithm:
def parse(arg, argv, &error)
if !(val = arg) and (argv.empty? or /\A-/ =~ (val = argv[0]))
return nil, block, nil # +1
end
opt = (val = parse_arg(val, &error))[1] # +2
val = conv_arg(*val) # +3
if opt and !arg
argv.shift # +4
else
val[0] = nil # +5
end
val # +6
end
(You might argue that the two assigments within the first @if@ should count as statements, and that perhaps the nested assignment should count as +2.)
EventPresenter#add_in_grid contains iterators nested 2 deep Open
selects = schedules.select { |schedule| schedule.day == index + 1 }
- Read upRead up
- Exclude checks
A Nested Iterator
occurs when a block contains another block.
Example
Given
class Duck
class << self
def duck_names
%i!tick trick track!.each do |surname|
%i!duck!.each do |last_name|
puts "full name is #{surname} #{last_name}"
end
end
end
end
end
Reek would report the following warning:
test.rb -- 1 warning:
[5]:Duck#duck_names contains iterators nested 2 deep (NestedIterators)
TalkInfoController#create has approx 6 statements Open
def create
- Read upRead up
- Exclude checks
A method with Too Many Statements
is any method that has a large number of lines.
Too Many Statements
warns about any method that has more than 5 statements. Reek's smell detector for Too Many Statements
counts +1 for every simple statement in a method and +1 for every statement within a control structure (if
, else
, case
, when
, for
, while
, until
, begin
, rescue
) but it doesn't count the control structure itself.
So the following method would score +6 in Reek's statement-counting algorithm:
def parse(arg, argv, &error)
if !(val = arg) and (argv.empty? or /\A-/ =~ (val = argv[0]))
return nil, block, nil # +1
end
opt = (val = parse_arg(val, &error))[1] # +2
val = conv_arg(*val) # +3
if opt and !arg
argv.shift # +4
else
val[0] = nil # +5
end
val # +6
end
(You might argue that the two assigments within the first @if@ should count as statements, and that perhaps the nested assignment should count as +2.)
EventPresenter#add_in_hash refers to 'enrollment' more than self (maybe move it to another class?) Open
user = enrollment.user
presents << user if enrollment.present?
actives << { user: user, enrollment: enrollment } if enrollment.active?
- Read upRead up
- Exclude checks
Feature Envy occurs when a code fragment references another object more often than it references itself, or when several clients do the same series of manipulations on a particular type of object.
Feature Envy reduces the code's ability to communicate intent: code that "belongs" on one class but which is located in another can be hard to find, and may upset the "System of Names" in the host class.
Feature Envy also affects the design's flexibility: A code fragment that is in the wrong class creates couplings that may not be natural within the application's domain, and creates a loss of cohesion in the unwilling host class.
Feature Envy often arises because it must manipulate other objects (usually its arguments) to get them into a useful form, and one force preventing them (the arguments) doing this themselves is that the common knowledge lives outside the arguments, or the arguments are of too basic a type to justify extending that type. Therefore there must be something which 'knows' about the contents or purposes of the arguments. That thing would have to be more than just a basic type, because the basic types are either containers which don't know about their contents, or they are single objects which can't capture their relationship with their fellows of the same type. So, this thing with the extra knowledge should be reified into a class, and the utility method will most likely belong there.
Example
Running Reek on:
class Warehouse
def sale_price(item)
(item.price - item.rebate) * @vat
end
end
would report:
Warehouse#total_price refers to item more than self (FeatureEnvy)
since this:
(item.price - item.rebate)
belongs to the Item class, not the Warehouse.