class RuboCop::Cop::Performance::RedundantMerge

This cop identifies places where `Hash#merge!` can be replaced by `Hash#[]=`.

@example

hash.merge!(a: 1)
hash.merge!({'key' => 'value'})
hash.merge!(a: 1, b: 2)

Constants

AREF_ASGN
MSG
WITH_MODIFIER_CORRECTION

Public Instance Methods

autocorrect(node) click to toggle source
# File lib/rubocop/cop/performance/redundant_merge.rb, line 37
def autocorrect(node)
  redundant_merge_candidate(node) do |receiver, pairs|
    new_source = to_assignments(receiver, pairs).join("\n")

    if node.parent && pairs.size > 1
      correct_multiple_elements(node, node.parent, new_source)
    else
      correct_single_element(node, new_source)
    end
  end
end
on_send(node) click to toggle source
# File lib/rubocop/cop/performance/redundant_merge.rb, line 31
def on_send(node)
  each_redundant_merge(node) do |redundant_merge_node|
    add_offense(redundant_merge_node)
  end
end

Private Instance Methods

correct_multiple_elements(node, parent, new_source) click to toggle source
# File lib/rubocop/cop/performance/redundant_merge.rb, line 86
def correct_multiple_elements(node, parent, new_source)
  if modifier_flow_control?(parent)
    new_source = rewrite_with_modifier(node, parent, new_source)
    node = parent
  else
    padding = "\n#{leading_spaces(node)}"
    new_source.gsub!(/\n/, padding)
  end

  ->(corrector) { corrector.replace(node.source_range, new_source) }
end
correct_single_element(node, new_source) click to toggle source
# File lib/rubocop/cop/performance/redundant_merge.rb, line 98
def correct_single_element(node, new_source)
  ->(corrector) { corrector.replace(node.source_range, new_source) }
end
each_redundant_merge(node) { |node| ... } click to toggle source
# File lib/rubocop/cop/performance/redundant_merge.rb, line 59
def each_redundant_merge(node)
  redundant_merge_candidate(node) do |receiver, pairs|
    next if non_redundant_merge?(node, receiver, pairs)

    yield node
  end
end
indent_width() click to toggle source
# File lib/rubocop/cop/performance/redundant_merge.rb, line 130
def indent_width
  @config.for_cop('IndentationWidth')['Width'] || 2
end
kwsplat_used?(pairs) click to toggle source
# File lib/rubocop/cop/performance/redundant_merge.rb, line 77
def kwsplat_used?(pairs)
  pairs.any?(&:kwsplat_type?)
end
leading_spaces(node) click to toggle source
# File lib/rubocop/cop/performance/redundant_merge.rb, line 126
def leading_spaces(node)
  node.source_range.source_line[/\A\s*/]
end
max_key_value_pairs() click to toggle source
# File lib/rubocop/cop/performance/redundant_merge.rb, line 134
def max_key_value_pairs
  Integer(cop_config['MaxKeyValuePairs'])
end
message(node) click to toggle source
# File lib/rubocop/cop/performance/redundant_merge.rb, line 51
def message(node)
  redundant_merge_candidate(node) do |receiver, pairs|
    assignments = to_assignments(receiver, pairs).join('; ')

    format(MSG, prefer: assignments, current: node.source)
  end
end
non_redundant_merge?(node, receiver, pairs) click to toggle source
# File lib/rubocop/cop/performance/redundant_merge.rb, line 67
def non_redundant_merge?(node, receiver, pairs)
  non_redundant_pairs?(receiver, pairs) ||
    kwsplat_used?(pairs) ||
    non_redundant_value_used?(receiver, node)
end
non_redundant_pairs?(receiver, pairs) click to toggle source
# File lib/rubocop/cop/performance/redundant_merge.rb, line 73
def non_redundant_pairs?(receiver, pairs)
  pairs.size > 1 && !receiver.pure? || pairs.size > max_key_value_pairs
end
non_redundant_value_used?(receiver, node) click to toggle source
# File lib/rubocop/cop/performance/redundant_merge.rb, line 81
def non_redundant_value_used?(receiver, node)
  node.value_used? &&
    !EachWithObjectInspector.new(node, receiver).value_used?
end
rewrite_with_modifier(node, parent, new_source) click to toggle source
# File lib/rubocop/cop/performance/redundant_merge.rb, line 114
def rewrite_with_modifier(node, parent, new_source)
  indent = ' ' * indent_width
  padding = "\n#{indent + leading_spaces(node)}"
  new_source.gsub!(/\n/, padding)

  format(WITH_MODIFIER_CORRECTION, keyword: parent.loc.keyword.source,
                                   condition: parent.condition.source,
                                   leading_space: leading_spaces(node),
                                   indent: indent,
                                   body: new_source).chomp
end
to_assignments(receiver, pairs) click to toggle source
# File lib/rubocop/cop/performance/redundant_merge.rb, line 102
def to_assignments(receiver, pairs)
  pairs.map do |pair|
    key, value = *pair

    key = key.sym_type? && pair.colon? ? ":#{key.source}" : key.source

    format(AREF_ASGN, receiver: receiver.source,
                      key: key,
                      value: value.source)
  end
end