Type Casting
A customer types "3" into Bean Cart's order form. The form hands your code the string "3", not the number 3, and 4.50 * "3" is an error. Converting between types, often called type casting, is a daily job. Ruby gives you two styles: a forgiving one and a strict one.
The rule
to_methods forgive; capitalisedInteger()andFloat()complain.
Ruby rarely converts types behind your back. Mixing a number and a string raises a TypeError:
1 + "2" # TypeError: String can't be coerced into Integer
"2" + 1 # TypeError: no implicit conversion of Integer into StringSo you convert explicitly. The forgiving methods start with to_. They always return something, even if the input is nonsense:
"3".to_i # => 3
"4.50".to_f # => 4.5
"3 lattes".to_i # => 3 (reads leading digits, ignores the rest)
"latte".to_i # => 0 (no digits at all)
12.to_s # => "12"
3.to_f # => 3.0
3.99.to_i # => 3 (cuts off the decimals, no rounding)
:tea.to_s # => "tea"
"tea".to_sym # => :teaThe strict conversions are methods named like classes. They raise an error if the whole input is not a valid number:
Integer("3") # => 3
Integer("3 lattes") # ArgumentError: invalid value for Integer()
Float("4.50") # => 4.5
Float("") # ArgumentError
Integer("3 lattes", exception: false) # => nilThe last form returns nil instead of raising, which is handy for checking input.
When building text, you rarely need to_s at all: interpolation calls it for you, so "Cups: #{12}" works.
The shortcut
Ask "Do I trust this input?" Values your own code produced, like a count you store as a string: to_i and to_f are fine. Values a person typed or a file supplied: use Integer() or Float(), so bad input fails loudly instead of turning into a silent 0.
The input
The customer typed
"three"in the quantity box.
Drills
Answer fast — trust the rule.
What does "12 cups".to_i return?
What does Integer("12 cups") do?
What is 4.99.to_i?
What happens with "Total: " + 9.0?
Remember
to_methods forgive;Integer()andFloat()complain about bad input.- Ask "do I trust this input?" Untrusted input gets the strict version.
- Trap:
"abc".to_iis a silent0, andto_itruncates rather than rounds.
