class RuboCop::Cop::Style::FloatDivision

Checks for division with integers coerced to floats. It is recommended to either always use ‘fdiv` or coerce one side only. This cop also provides other options for code consistency.

@safety

This cop is unsafe, because if the operand variable is a string object
then `.to_f` will be removed and an error will occur.

[source,ruby]
----
a = '1.2'
b = '3.4'
a.to_f / b.to_f # Both `to_f` calls are required here
----

@example EnforcedStyle: single_coerce (default)

# bad
a.to_f / b.to_f

# good
a.to_f / b
a / b.to_f

@example EnforcedStyle: left_coerce

# bad
a / b.to_f
a.to_f / b.to_f

# good
a.to_f / b

@example EnforcedStyle: right_coerce

# bad
a.to_f / b
a.to_f / b.to_f

# good
a / b.to_f

@example EnforcedStyle: fdiv

# bad
a / b.to_f
a.to_f / b
a.to_f / b.to_f

# good
a.fdiv(b)

Constants

MESSAGES
RESTRICT_ON_SEND

Public Instance Methods

on_send(node) click to toggle source
# File lib/rubocop/cop/style/float_division.rb, line 83
def on_send(node)
  return unless offense_condition?(node)

  add_offense(node) do |corrector|
    case style
    when :left_coerce, :single_coerce
      add_to_f_method(corrector, node.receiver)
      remove_to_f_method(corrector, node.first_argument)
    when :right_coerce
      remove_to_f_method(corrector, node.receiver)
      add_to_f_method(corrector, node.first_argument)
    when :fdiv
      correct_from_slash_to_fdiv(corrector, node, node.receiver, node.first_argument)
    end
  end
end

Private Instance Methods

add_to_f_method(corrector, node) click to toggle source
# File lib/rubocop/cop/style/float_division.rb, line 121
def add_to_f_method(corrector, node)
  corrector.insert_after(node, '.to_f') unless node.send_type? && node.method?(:to_f)
end
correct_from_slash_to_fdiv(corrector, node, receiver, argument) click to toggle source
# File lib/rubocop/cop/style/float_division.rb, line 130
def correct_from_slash_to_fdiv(corrector, node, receiver, argument)
  receiver_source = extract_receiver_source(receiver)
  argument_source = extract_receiver_source(argument)

  if argument.respond_to?(:parenthesized?) && !argument.parenthesized?
    argument_source = "(#{argument_source})"
  end

  corrector.replace(node, "#{receiver_source}.fdiv#{argument_source}")
end
extract_receiver_source(node) click to toggle source
# File lib/rubocop/cop/style/float_division.rb, line 141
def extract_receiver_source(node)
  if node.send_type? && node.method?(:to_f)
    node.receiver.source
  else
    node.source
  end
end
message(_node) click to toggle source
# File lib/rubocop/cop/style/float_division.rb, line 117
def message(_node)
  MESSAGES[style]
end
offense_condition?(node) click to toggle source
# File lib/rubocop/cop/style/float_division.rb, line 102
def offense_condition?(node)
  case style
  when :left_coerce
    right_coerce?(node)
  when :right_coerce
    left_coerce?(node)
  when :single_coerce
    both_coerce?(node)
  when :fdiv
    any_coerce?(node)
  else
    false
  end
end
remove_to_f_method(corrector, send_node) click to toggle source
# File lib/rubocop/cop/style/float_division.rb, line 125
def remove_to_f_method(corrector, send_node)
  corrector.remove(send_node.loc.dot)
  corrector.remove(send_node.loc.selector)
end