lib/reek/smells.rb in reek-0.2.2 vs lib/reek/smells.rb in reek-0.2.3
- old
+ new
@@ -16,16 +16,13 @@
@context = context
end
def self.check(exp, context, arg=nil)
smell = new(context, arg)
- if smell.recognise?(exp)
- context.report(smell)
- true
- else
- false
- end
+ return false unless smell.recognise?(exp)
+ context.report(smell)
+ true
end
def recognise?(stuff)
@context != nil
end
@@ -97,51 +94,43 @@
"#{@context} has approx #{@num_stmts} statements"
end
end
class FeatureEnvy < Smell
-
- # TODO
- # Should be moved to Hash; but Hash has 58 methods, and there's currently
- # no way to turn off that report; which would therefore make the tests fail
- def self.max_keys(calls)
- max = calls.values.max or return [:self]
- calls.keys.select { |key| calls[key] == max }
- end
- def initialize(context, *receivers)
- super(context)
- @receivers = receivers
+ def recognise?(refs)
+ @refs = refs
+ !refs.self_is_max?
end
- def recognise?(calls)
- @receivers = FeatureEnvy.max_keys(calls)
- return !(@receivers.include?(:self))
- end
-
def detailed_report
- receiver = @receivers.map {|r| Printer.print(r)}.sort.join(' and ')
+ receiver = @refs.max_keys.map {|r| Printer.print(r)}.sort.join(' and ')
"#{@context} uses #{receiver} more than self"
end
end
class UtilityFunction < Smell
- def recognise?(calls)
- calls[:self] == 0
+ def recognise?(depends_on_self)
+ !depends_on_self
end
def detailed_report
"#{@context} doesn't depend on instance state"
end
end
class LargeClass < Smell
MAX_ALLOWED = 25
+ def self.non_inherited_methods(klass)
+ return klass.instance_methods if klass.superclass.nil?
+ klass.instance_methods - klass.superclass.instance_methods
+ end
+
def recognise?(name)
klass = Object.const_get(name) rescue return
- @num_methods = klass.instance_methods.length - klass.superclass.instance_methods.length
+ @num_methods = LargeClass.non_inherited_methods(klass).length
@num_methods > MAX_ALLOWED
end
def detailed_report
"#{@context} has #{@num_methods} methods"
@@ -152,14 +141,18 @@
def initialize(context, symbol_type)
super
@symbol_type = symbol_type
end
+ def self.effective_length(name)
+ return 500 if name == '*'
+ name = name[1..-1] while /^@/ === name
+ name.length
+ end
+
def recognise?(symbol)
@symbol = symbol.to_s
- return false if @symbol == '*'
- min_len = (/^@/ === @symbol) ? 3 : 2;
- @symbol.length < min_len
+ UncommunicativeName.effective_length(@symbol) < 2
end
def detailed_report
"#{@context} uses the #{@symbol_type} name '#{@symbol}'"
end