class RuboCop::Cop::Performance::RedundantStringChars
.chars<br>str.chars
# good
str.chars.empty?
str.chars.size
str.chars.length
str.chars.drop(2)
str.chars.take(2)
# bad<br><br>str.chars<br>str[-1]<br>str.chars
str[0]
# good
str.chars.last(2)
str.chars.last
str.chars.first(2)
str.chars.first
# bad<br><br>str.chars
# good
str.chars.slice(0..2)
str.chars[0..2]
# bad
@example
This cop checks for redundant ‘String#chars`.
def autocorrect(node)
def autocorrect(node) redundant_chars_call?(node) do |receiver, method, args| range = correction_range(receiver, node) replacement = build_good_method(method, args) lambda do |corrector| corrector.replace(range, replacement) end end end
def build_bad_method(method, args)
def build_bad_method(method, args) case method when :[] "chars[#{build_call_args(args)}]" else if args.any? "chars.#{method}(#{build_call_args(args)})" else "chars.#{method}" end end end
def build_call_args(call_args_node)
def build_call_args(call_args_node) call_args_node.map(&:source).join(', ') end
def build_good_method(method, args)
def build_good_method(method, args) case method when :[], :slice "[#{build_call_args(args)}].chars" when :first if args.any? "[0...#{args.first.source}].chars" else '[0]' end when :last if args.any? "[-#{args.first.source}..-1].chars" else '[-1]' end when :take "[0...#{args.first.source}].chars" when :drop "[#{args.first.source}..-1].chars" else ".#{method}" end end
def build_message(method, args)
def build_message(method, args) good_method = build_good_method(method, args) bad_method = build_bad_method(method, args) format(MSG, good_method: good_method, bad_method: bad_method) end
def correction_range(receiver, node)
def correction_range(receiver, node) range_between(receiver.loc.dot.begin_pos, node.loc.expression.end_pos) end
def offense_range(receiver, node)
def offense_range(receiver, node) range_between(receiver.loc.selector.begin_pos, node.loc.expression.end_pos) end
def on_send(node)
def on_send(node) redundant_chars_call?(node) do |receiver, method, args| range = offense_range(receiver, node) message = build_message(method, args) add_offense(node, location: range, message: message) end end
def replaceable_method?(method_name)
def replaceable_method?(method_name) REPLACEABLE_METHODS.include?(method_name) end