Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Undefined method `-' for "100":String

This Ruby code:

income = "100"
bills  = "52"

puts income - bills

threw an error:

./to_f.rb:6: undefined method `-' for "100":String (NoMethodError)

Does Ruby not auto-convert strings to numbers when performing math operations on them?

like image 897
JD. Avatar asked Sep 26 '12 14:09

JD.


2 Answers

Ruby is a dynamically-typed, strictly-typed (or "strongly-typed") language. Lua is another such language. The former means that variables can hold any class of value. The latter—what you are running into—means that type coercion does not happen automatically.

Contrast these with JavaScript, which is dynamically-typed and loosely-typed. In JavaScript you can write var x = [] + false; and it will attempt to do something helpful. For another example, in JavaScript "1" + 1 == "11" but "1" - 1 == 0. Ruby will not do any such thing.

In your case you need:

puts income.to_i - bills.to_i

Note that—because most operators are implemented as methods in Ruby—each class can choose how the operator handles operands of various types. For example:

class Person
  def +( something )
    if something.is_a?(Numeric)
      self.weight += something
    elsif something.is_a?(Time)
      self.age += something
    else
      raise "I don't know how to add a #{something.class} to a Person."
    end
  end
end

Most of the time the core libraries do not attempt to be so clever, however.

like image 66
Phrogz Avatar answered Nov 28 '22 09:11

Phrogz


Because strings can be concatenated using the + operator, it will not always be clear whether you want to append or sum two strings holding number values.

If you have two strings holding numbers, convert them to the appropriate values (int or float) before doing any math on them:

income = "100"
bills  = "52"

puts income.to_f - bills.to_f
like image 25
JD. Avatar answered Nov 28 '22 11:11

JD.