diff --git a/changelog/change_make_lint_number_conversion_aware_of_rational.md b/changelog/change_make_lint_number_conversion_aware_of_rational.md new file mode 100644 index 00000000000..279a3e0c738 --- /dev/null +++ b/changelog/change_make_lint_number_conversion_aware_of_rational.md @@ -0,0 +1 @@ +* [#10236](https://github.com/rubocop/rubocop/pull/10236): Make `Lint/NumberConversion` aware of `to_r`. ([@koic][]) diff --git a/lib/rubocop/cop/lint/number_conversion.rb b/lib/rubocop/cop/lint/number_conversion.rb index fd9e1b7871d..4e2c8472fb4 100644 --- a/lib/rubocop/cop/lint/number_conversion.rb +++ b/lib/rubocop/cop/lint/number_conversion.rb @@ -30,6 +30,7 @@ module Lint # '10'.to_i # '10.2'.to_f # '10'.to_c + # '1/3'.to_r # ['1', '2', '3'].map(&:to_i) # foo.try(:to_f) # bar.send(:to_c) @@ -39,6 +40,7 @@ module Lint # Integer('10', 10) # Float('10.2') # Complex('10') + # Rational('1/3') # ['1', '2', '3'].map { |i| Integer(i, 10) } # foo.try { |i| Float(i) } # bar.send { |i| Complex(i) } @@ -59,13 +61,14 @@ class NumberConversion < Base CONVERSION_METHOD_CLASS_MAPPING = { to_i: "#{Integer.name}(%s, 10)", to_f: "#{Float.name}(%s)", - to_c: "#{Complex.name}(%s)" + to_c: "#{Complex.name}(%s)", + to_r: "#{Rational.name}(%s)" }.freeze MSG = 'Replace unsafe number conversion with number '\ 'class parsing, instead of using '\ '`%s`, use stricter '\ '`%s`.' - CONVERSION_METHODS = %i[Integer Float Complex to_i to_f to_c].freeze + CONVERSION_METHODS = %i[Integer Float Complex Rational to_i to_f to_c to_r].freeze METHODS = CONVERSION_METHOD_CLASS_MAPPING.keys.map(&:inspect).join(' ') # @!method to_method(node) diff --git a/spec/rubocop/cop/lint/number_conversion_spec.rb b/spec/rubocop/cop/lint/number_conversion_spec.rb index 0a4e6e36235..1becedbd0be 100644 --- a/spec/rubocop/cop/lint/number_conversion_spec.rb +++ b/spec/rubocop/cop/lint/number_conversion_spec.rb @@ -35,6 +35,17 @@ RUBY end + it 'when using `#to_r`' do + expect_offense(<<~RUBY) + "1/3".to_r + ^^^^^^^^^^ Replace unsafe number conversion with number class parsing, instead of using `"1/3".to_r`, use stricter `Rational("1/3")`. + RUBY + + expect_correction(<<~RUBY) + Rational("1/3") + RUBY + end + it 'when using `#to_i` for number literals' do expect_no_offenses(<<~RUBY) 42.to_i @@ -56,6 +67,13 @@ RUBY end + it 'when using `#to_r` for number literals' do + expect_no_offenses(<<~RUBY) + 42.to_r + 42.0.to_r + RUBY + end + it 'when `#to_i` called on a variable' do expect_offense(<<~RUBY) string_value = '10'