class RuboCop::Cop::Style::SlicingWithRange
Checks that arrays are not sliced with the redundant ‘ary`, replacing it with `ary`, and ensures arrays are sliced with endless ranges instead of `ary` on Ruby 2.6+, and with beginless ranges instead of `ary` on Ruby 2.7+.
@safety
This cop is unsafe because `x..-1` and `x..` are only guaranteed to be equivalent for `Array#[]`, `String#[]`, and the cop cannot determine what class the receiver is. For example: [source,ruby] ---- sum = proc { |ary| ary.sum } sum[-3..-1] # => -6 sum[-3..] # Hangs forever ----
@example
# bad items[0..-1] items[0..nil] items[0...nil] # good items # bad items[1..-1] # Ruby 2.6+ items[1..nil] # Ruby 2.6+ # good items[1..] # Ruby 2.6+ # bad items[nil..42] # Ruby 2.7+ # good items[..42] # Ruby 2.7+ items[0..42] # Ruby 2.7+
Constants
- MSG
- MSG_USELESS_RANGE
- RESTRICT_ON_SEND
Public Instance Methods
on_send(node)
click to toggle source
# File lib/rubocop/cop/style/slicing_with_range.rb, line 77 def on_send(node) return unless node.arguments.one? range_node = node.first_argument selector = node.loc.selector unless (message, removal_range = offense_message_with_removal_range(range_node, selector)) return end add_offense(selector, message: message) do |corrector| corrector.remove(removal_range) end end
Private Instance Methods
beginless(range_node)
click to toggle source
# File lib/rubocop/cop/style/slicing_with_range.rb, line 111 def beginless(range_node) "[#{range_node.loc.operator.source}#{range_node.end.source}]" end
endless(range_node)
click to toggle source
# File lib/rubocop/cop/style/slicing_with_range.rb, line 107 def endless(range_node) "[#{range_node.begin.source}#{range_node.loc.operator.source}]" end
offense_message_with_removal_range(range_node, selector)
click to toggle source
# File lib/rubocop/cop/style/slicing_with_range.rb, line 93 def offense_message_with_removal_range(range_node, selector) if range_from_zero_till_minus_one?(range_node) [format(MSG_USELESS_RANGE, prefer: selector.source), selector] elsif range_till_minus_one?(range_node) [ format(MSG, prefer: endless(range_node), current: selector.source), range_node.end ] elsif range_from_zero?(range_node) && target_ruby_version >= 2.7 [ format(MSG, prefer: beginless(range_node), current: selector.source), range_node.begin ] end end