diff --git a/lib/fasterer/method_call.rb b/lib/fasterer/method_call.rb index be8e420..9d8fbf4 100644 --- a/lib/fasterer/method_call.rb +++ b/lib/fasterer/method_call.rb @@ -9,6 +9,10 @@ class MethodCall alias_method :name, :method_name + # Defines CONSTANT_TYPES constant with the list of constant + # types like String, Nil, Integer, Symbol, Boolean or a Contant + PRIMITIVE_DATA_TYPES = %i[nil lit str const true false].freeze + def initialize(element) @element = element set_call_element @@ -24,6 +28,10 @@ def has_block? @block_present || false end + def has_block_with_primitive_data_types? + has_block? && PRIMITIVE_DATA_TYPES.include?(@block_body.first) + end + def receiver_element call_element[1] end diff --git a/lib/fasterer/offense.rb b/lib/fasterer/offense.rb index 883b7b1..0a9038f 100644 --- a/lib/fasterer/offense.rb +++ b/lib/fasterer/offense.rb @@ -44,7 +44,7 @@ def explanation 'Enumerable#sort is slower than Enumerable#sort_by', fetch_with_argument_vs_block: - 'Hash#fetch with second argument is slower than Hash#fetch with block', + 'Hash#fetch with block of primitive data types like: String, Integer, Symbol, Boolean or Nil is slower than Hash#fetch with second argument', keys_each_vs_each_key: 'Hash#keys.each is slower than Hash#each_key. N.B. Hash#each_key cannot be used if the hash is modified during the each block', diff --git a/lib/fasterer/scanners/method_call_scanner.rb b/lib/fasterer/scanners/method_call_scanner.rb index a8f976e..6251c93 100644 --- a/lib/fasterer/scanners/method_call_scanner.rb +++ b/lib/fasterer/scanners/method_call_scanner.rb @@ -114,7 +114,7 @@ def check_flatten_offense end def check_fetch_offense - if method_call.arguments.count == 2 && !method_call.has_block? + if method_call.arguments.count == 1 && method_call.has_block_with_primitive_data_types? add_offense(:fetch_with_argument_vs_block) end end diff --git a/spec/lib/fasterer/analyzer/14_fetch_with_argument_vs_block_spec.rb b/spec/lib/fasterer/analyzer/14_fetch_with_argument_vs_block_spec.rb index 18a2fa1..6a8002a 100644 --- a/spec/lib/fasterer/analyzer/14_fetch_with_argument_vs_block_spec.rb +++ b/spec/lib/fasterer/analyzer/14_fetch_with_argument_vs_block_spec.rb @@ -6,6 +6,6 @@ it 'should detect keys fetch with argument once' do analyzer = Fasterer::Analyzer.new(test_file_path) analyzer.scan - expect(analyzer.errors[:fetch_with_argument_vs_block].count).to eq(1) + expect(analyzer.errors[:fetch_with_argument_vs_block].count).to eq(4) end end diff --git a/spec/support/analyzer/14_fetch_with_argument_vs_block.rb b/spec/support/analyzer/14_fetch_with_argument_vs_block.rb index 4bc223f..0ee1667 100644 --- a/spec/support/analyzer/14_fetch_with_argument_vs_block.rb +++ b/spec/support/analyzer/14_fetch_with_argument_vs_block.rb @@ -1,11 +1,23 @@ HASH = { :writing => :fast_ruby } def slow - HASH.fetch(:writing, [*1..100]) + HASH.fetch(:writing) { nil } +end + +def slow + HASH.fetch(:writing) { 1 } +end + +def slow + HASH.fetch(:writing) { "1" } +end + +def slow + HASH.fetch(:writing) { true } end def fast - HASH.fetch(:writing) { [*1..100] } + HASH.fetch(:writng, 1) end HASH.fetch(:writing)