class Reek::SmellDetectors::MissingSafeMethod
Excerpt from: dablog.rubypal.com/2007/8/15/bang-methods-or-danger-will-rubyist since this sums it up really well:
The ! in method names that end with ! means, "This method is dangerous" -- or, more precisely, this method is the "dangerous" version of an equivalent method, with the same name minus the !. "Danger" is relative; the ! doesn't mean anything at all unless the method name it's in corresponds to a similar but bang-less method name. Don't add ! to your destructive (receiver-changing) methods' names, unless you consider the changing to be "dangerous" and you have a "non-dangerous" equivalent method without the !. If some arbitrary subset of destructive methods end with !, then the whole point of ! gets distorted and diluted, and ! ceases to convey any information whatsoever.
Such a method is called MissingSafeMethod
and is reported as a smell.
See {file:docs/Missing-Safe-Method.md} for details.
Public Instance Methods
Source
# File lib/reek/smell_detectors/missing_safe_method.rb, line 49 def sniff context.node_instance_methods.select do |method_sexp| missing_safe_method?(method_sexp) end.map do |method_sexp| name = method_sexp.name smell_warning( lines: [method_sexp.line], message: "has missing safe method '#{name}'", parameters: { name: name.to_s }) end end
@return [Array<SmellWarning>]
Given this code:
class Alfa
def bravo! end
end
An example context could look like this:
s(:class,
s(:const, nil, :Alfa), nil, s(:def, :bravo!, s(:args), nil))
Private Instance Methods
Source
# File lib/reek/smell_detectors/missing_safe_method.rb, line 82 def ignore_method?(method_node) ignore_method_names.include? method_node.name.to_s # method_node.name is e.g.: :bravo! end
@param method_node [Reek::AST::Node],
e.g. s(:def, :bravo!, s(:args), nil)
@return [Boolean]
Source
# File lib/reek/smell_detectors/missing_safe_method.rb, line 87 def ignore_method_names @ignore_method_names ||= value(EXCLUDE_KEY, context) end
e.g. [“bravo!”]
Source
# File lib/reek/smell_detectors/missing_safe_method.rb, line 63 def missing_safe_method?(method_sexp) return false unless method_sexp.ends_with_bang? return false if ignore_method? method_sexp return false if version_without_bang_exists? method_sexp true end
Source
# File lib/reek/smell_detectors/missing_safe_method.rb, line 71 def version_without_bang_exists?(method_sexp) context.node_instance_methods.find do |sexp_item| sexp_item.name.to_s == method_sexp.name_without_bang end end