Variables, numbers and nil

Ruby · Essentials · 10 min

Ruby's simple truthiness rule and its numeric types shape how every condition and calculation behaves.

Local variables need no declaration: count = 3. Names are snake_case. Constants start with a capital letter, MAX_SIZE = 10, and Ruby warns if you reassign one.

Core value types:

  • Integer has arbitrary precision: 2**100 just works. Integer division truncates toward negative infinity: 7 / 2 is 3 and -7 / 2 is -4. Use 7.fdiv(2) or a float operand for 3.5.
  • Float is a double: 0.1 + 0.2 is 0.30000000000000004. Use Rational or BigDecimal for money.
  • String is mutable text, and Symbol (:name) is an immutable, interned name, mostly used as hash keys and identifiers.
  • true, false and nil ("no value").

The truthiness rule is simple: only `false` and `nil` are falsy. 0, "" and [] are all truthy, unlike in many languages. Check for nothing with x.nil? and for emptiness with empty?.

Conversions are explicit: "42".to_i, "3.5".to_f, 42.to_s, :sym.to_s, "str".to_sym. The lenient "12abc".to_i returns 12; the strict Integer("12abc") raises ArgumentError, which is what you want for validating input.

x ||= 5 assigns only if x is nil or false, a common idiom for defaults and memoisation. Safe navigation user&.name returns nil instead of raising when user is nil.

Example

count = 3
price = 9.5
big = 2**100
puts big                 # 1267650600228229401496703205376
puts 7 / 2, -7 / 2       # 3, -4
puts 7.fdiv(2)           # 3.5
puts 0.1 + 0.2           # 0.30000000000000004

puts "zero is truthy" if 0     # zero is truthy
puts [nil, false, 0, ""].map { |v| v ? "T" : "F" }.join  # FFTT

puts "12abc".to_i        # 12
begin
  Integer("12abc")
rescue ArgumentError
  puts "strict parse failed"   # strict parse failed
end

name = nil
name ||= "guest"
p name                   # "guest"
p nil&.length            # nil

Remember

  • Only false and nil are falsy; 0 and "" are truthy
  • Integers are arbitrary precision and / on integers truncates
  • Use Integer() and Float() for strict parsing, to_i for lenient

Watch out for

  • Writing if count.zero? style checks as if count, which is always true for numbers.

Check yourself

  1. Which of these values is falsy in Ruby?
  2. What is -7 / 2 in Ruby?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.ruby-lang.org/en/3.4/syntax/literals_rdoc.html