class Gitlab::Styles::Rubocop::Cop::Style::HashTransformation
This cop identifies places where `map { … }.to_h` or `Hash[map { … }]` can be replaced with `to_h { … }`, saving an intermediate array allocation.
@example
# bad hash.map { |k, v| [v.upcase, k.downcase] }.to_h hash.collect { |k, v| [v.upcase, k.downcase] }.to_h Hash[hash.map { |k, v| [v.upcase, k.downcase] }] Hash[hash.collect { |k, v| [v.upcase, k.downcase] }] array.map { |x| [x, x + 1] }.to_h # good hash.to_h { |k, v| [v.upcase, k.downcase] } array.to_h { |x| [x, x + 1] }
Full credit: github.com/eugeneius/rubocop-performance/blob/hash_transformation/lib/rubocop/cop/performance/hash_transformation.rb
Constants
- MSG
Public Instance Methods
autocorrect(node)
click to toggle source
# File lib/gitlab/styles/rubocop/cop/style/hash_transformation.rb, line 47 def autocorrect(node) block, call = to_h_candidate?(node) lambda do |corrector| corrector.remove(after_block(node, block)) corrector.replace(call.loc.selector, 'to_h') corrector.remove(before_block(node, block)) end end
on_send(node)
click to toggle source
# File lib/gitlab/styles/rubocop/cop/style/hash_transformation.rb, line 39 def on_send(node) to_h_candidate?(node) do |_block, call| range = offense_range(node, call) message = message(node, call) add_offense(node, location: range, message: message) end end
Private Instance Methods
after_block(node, block)
click to toggle source
# File lib/gitlab/styles/rubocop/cop/style/hash_transformation.rb, line 75 def after_block(node, block) block.source_range.end.join(node.source_range.end) end
before_block(node, block)
click to toggle source
# File lib/gitlab/styles/rubocop/cop/style/hash_transformation.rb, line 79 def before_block(node, block) node.source_range.begin.join(block.source_range.begin) end
message(node, call)
click to toggle source
# File lib/gitlab/styles/rubocop/cop/style/hash_transformation.rb, line 65 def message(node, call) current = if node.children.first.const_type? "Hash[#{call.method_name} { ... }]" else "#{call.method_name} { ... }.to_h" end format(MSG, current: current) end
offense_range(node, call)
click to toggle source
# File lib/gitlab/styles/rubocop/cop/style/hash_transformation.rb, line 59 def offense_range(node, call) return node.source_range if node.children.first.const_type? range_between(call.loc.selector.begin_pos, node.loc.selector.end_pos) end