Everything Is an Object
Understand Ruby's pure object model — why numbers, strings, and even nil are real objects with real methods, and what that unlocks.
Introduction
This is the single most important lesson in this course. In many languages, a number or a boolean is a "primitive" — a special, lightweight value that isn't a real object and has no methods of its own. Ruby rejects that distinction entirely: everything, without exception, is a genuine object.
- How to call methods directly on numbers, strings, and other values you might expect to be "primitives."
- How method chaining lets you compose several operations into one readable expression.
- Why even nil is a real object, and what that means in practice.
- What duck typing is, and how it relates to Ruby's object model.
Calling Methods on "Primitives"
Because a plain integer is a real object, it has real, callable methods — no wrapper class or special syntax required.
puts 5.times.to_a # [0, 1, 2, 3, 4]puts (-7).abs # 7puts 3.14.round # 3puts "hello".upcase # HELLOputs "hello".reverse # ollehClick Run to see what this code prints.
5.times { ... }, seen throughout this course's examples, is exactly this same mechanism — 5 is an Integer object, and .times is simply one of the many methods that object provides.
Method Chaining
Because calling a method on an object often returns another object, you can chain multiple method calls together in one readable expression — a style that appears constantly in idiomatic Ruby.
result = " Hello, Ruby World! ".strip.downcase.split(" ").firstputs resultClick Run to see what this code prints.
Reading right to left through the chain: .strip removes surrounding whitespace, .downcase lowercases it, .split(" ") turns it into an array of words, and .first grabs the first one — four operations, one clean line.
nil Is an Object Too
Even nil — Ruby's representation of "no value" — is an object of its own class, NilClass, with its own methods, including a very commonly used one: .nil?
value = nil
puts value.class # NilClassputs value.nil? # trueputs value.to_s # "" (an empty string)puts value.to_a # [] (an empty array)Click Run to see what this code prints.
Because nil responds to methods like .to_s and .to_a instead of crashing immediately, some code that would raise a null-pointer-style error in other languages behaves predictably in Ruby — though calling a method nil truly doesn't support (like .upcase) still raises a clear NoMethodError.
Discovering Methods with .methods
Because every object carries its own list of available methods, you can ask any object what it can do — genuinely useful while learning or exploring an unfamiliar object.
puts 42.respond_to?(:times) # trueputs "hello".respond_to?(:times) # falseClick Run to see what this code prints.
Duck Typing
Ruby's object model, combined with its dynamic typing, leads naturally to "duck typing" — the idea that an object's suitability for a task is judged by whether it responds to the methods you need, not by its declared type. "If it walks like a duck and quacks like a duck, treat it like a duck."
def describe_length(item) puts "Length is #{item.length}"end
describe_length("hello") # String responds to .lengthdescribe_length([1, 2, 3]) # Array responds to .length tooClick Run to see what this code prints.
Common Mistakes
- Treating Ruby's numbers and booleans as lightweight primitives out of habit from another language — in Ruby, they're genuinely full objects.
- Calling a method on a value that might be nil without checking first, and being surprised by a NoMethodError.
- Chaining so many methods together that a line becomes hard to read — chaining is a style choice, not an obligation.
Best Practices
- Use value.nil? to check for "no value" explicitly rather than relying only on Ruby's general truthy/falsy rule when clarity matters.
- Use method chaining for a clear, linear sequence of transformations, but break longer chains into named intermediate steps if readability suffers.
- Lean into duck typing rather than manually checking is_a?(SomeClass) everywhere — Ruby idiomatically favors "does it respond to what I need," not "is it exactly this type."
Frequently Asked Questions
There is some overhead compared to languages with true unboxed primitives, though modern Ruby (with YJIT, covered in lesson 2) has narrowed that gap significantly for many real workloads.
No — the concept appears in Python and other dynamically typed languages too, but Ruby's pure object model and flexible method-based style make it an especially natural fit.
Ruby raises a NoMethodError at runtime, naming the exact method and object type involved — a common and usually easy-to-fix error while learning.
Key Takeaways
- Every value in Ruby, including numbers and booleans, is a real object with callable methods.
- Method chaining composes several operations into one readable expression.
- nil is a real object (NilClass) with its own methods, including the commonly used .nil?
- Duck typing judges an object by whether it responds to needed methods, not by its declared type.
Summary
Ruby's pure object model is why its code so often reads as a fluent chain of small, clear operations rather than a wall of separate statements. Next, you'll cover control flow: if/unless, loops, and Ruby's distinctive statement modifiers.