The
Assignment Branch Condition size
warning is a complexity warning; your method is too complex. This is stated in convoluted language, but it's actually just a measurement of how many assignments, branches, and conditions you have in your method (a "branch" is a method call). To compute this metric, rubocop computes the number of assignments (call it A
), the number of branches (B
), and the number of conditions (C
), then computes Math.sqrt(A**2 + B**2 + C**2)
. If the resulting value is greater than some size (18 by default), the method is said to exceed the Abc size, and rubocop complains.
Fixing this is a matter of eliminating assignments, branches, and conditions from your method, either by simplifying the code, or by doing some sort of refactoring.
Note that ruby tends to hide a lot of method calls (branches). For instance, if you have a getter defined in your class, every reference to that getter is a method call, even though it looks like a simple variable. Additionally, every indexing operation (e.g.,
array[1]
) is a method call. These two hidden method calls are a major source of Abc complaints in ruby programs.
So, for example, if you have this class:
class Example
attr_reader :something
def initialize
@something = [...]
end
def print_something
if something.size == 0
puts "something has just 1 item: #{something[0]}"
elsif something.size == 1
puts "something has 2 items: #{something[0]} #{something[1]}"
else
puts "something has #{something.size} items: #{something.join(' ')}"
end
end
end
rubocop will complain about the Abc size for
print_something
. This is primarily because we are calling the something
getter 7 times, calling the []
method on something
3 times, calling something.size
3 times, and calling something.join
once. That's enough to account for 14 Abc size units. (We also need to count 2 conditions, 3 calls to puts
, and one call to join
).
A simple fix in this case is to eliminate all of the calls to the
something
getter by just accessing @something
directly, or by savingsomething
to a local variable, and then using that variable instead of the getter.value = something
if value.size == 0
...
Comments
Post a Comment