Overview
7 Built-in essentials
This chapter serves as a next‑level Ruby literacy guide, surveying core language “essentials” you’ll rely on everywhere. It explains how Ruby’s built-in classes and syntax work together: literal object construction, operator-style syntactic sugar, the to_* conversion family, truthiness and nil, object comparison patterns, and runtime reflection. The goal is to make these mechanics second nature so later code reads naturally and you can reason confidently about what Ruby will do in common situations.
It begins with literal constructors for common classes (such as strings, symbols, arrays, hashes, ranges, regexps, and lambdas) and then shows how operators are just methods, enabling you to customize behavior by defining +, -, [], <<, comparison operators, and even unary +@, -@, and !. The chapter clarifies the role and conventions of bang methods: they signal a “heads up” variation—often, but not always, destructive—paired with a non‑bang counterpart. Conversion methods get deep coverage: to_s (and inspect/display contexts), to_a and its tight integration with the splat operator, numeric conversions via to_i/to_f versus stricter Integer/Float, and the “role‑playing” to_str and to_ary that let objects stand in for core types where a true string or array is required.
On truth values, Ruby treats everything as truthy except false and nil, and it examines these as actual objects (TrueClass, FalseClass, NilClass) as well as boolean states, highlighting practical consequences (for example, 0 and "" are truthy). For comparisons, it distinguishes ==, eql?, and equal?, and shows how to equip your own classes with full ordering by mixing in Comparable and defining the spaceship operator (<=>). Finally, it equips you with reflection tools—methods, singleton_methods, instance_methods (with or without ancestors), and visibility‑filtered queries—so you can inspect capabilities at runtime, experiment in irb, and navigate Ruby’s method lookup with precision.
Summary
- Ruby’s literal constructors provide an alternative to calling new on certain built-in classes.
- Ruby includes some “syntactic sugar” that uses operator syntax to call methods.
- Methods that change their receiver permanently are known as “destructive” methods.
- Method names in Ruby can end with an exclamation point; these are known as “bang methods.”
- “Bang” methods are often destructive, but also exhibit other kinds of “danger” (for example, Kernel#exit!).
- There are numerous built-in conversion methods (to_s and friends), and you can write your own for your classes.
- Every object in Ruby has a Boolean value.
- Boolean state is represented by the special objects true and false.
- The special object nil represents a state of undefinedness or absence.
- The Comparable module offers a set of comparison methods (operators), all based off of the “spaceship” operator (<=>).
- Ruby includes facilities for examining an object’s available methods.
FAQ
What are Ruby’s literal constructors and why do they matter?
They’re special syntaxes that create objects without calling new. Common ones:
- String: "text" or 'text'
- Symbol: :name or :"with spaces"
- Array: [1, 2, 3]
- Hash: {"NY" => "New York"} or {NY: "New York"}
- Range: 1..5 (inclusive), 1...5 (exclusive end)
- Regexp: /pattern/
- Proc (lambda): ->(x, y) { x * y }
They’re concise, ubiquitous, and instantly signal the object’s type by sight.
What does “syntactic sugar” mean in Ruby, and how can I define operators?
Syntactic sugar lets you call methods with nicer operator-like syntax. If your class defines methods like +, -, *, /, %, **, <<, [], []=, <, >, <=, >=, ==, ===, &, |, ^, you can write obj + other instead of obj.+(other). Compound assignments (+=, -=, etc.) work automatically when the corresponding operator method exists.
Can I customize unary operators like +obj, -obj, and !obj?
Yes. Define:
- +@ and -@ for unary plus/minus (for example, to toggle case or sign)
- ! to implement logical “not” (also powers the keyword not)
Example idea: implement +@ to upcase a wrapper’s text, -@ to downcase it, and ! to reverse it.
What are bang (!) methods and when should I use them?
By convention, a ! at the end (like upcase!) flags a “dangerous” variant of a similarly named method without !. Often “dangerous” means it mutates the receiver (e.g., String#upcase! vs String#upcase), but it can also mean different return values or bypassing safeguards (e.g., exit!). Best practice: only use ! when there’s a non-bang counterpart that does the same thing more safely or non-destructively.
What’s the difference between to_s, inspect, and display?
- to_s: Canonical string form. puts calls to_s; string interpolation #{obj} uses to_s.
- inspect: Developer-focused representation (irb prints values via inspect). Override it for meaningful debug output.
- display(io = STDOUT): Writes the object to a given IO (defaults to STDOUT) without adding a newline; returns nil.
How do to_a and the splat (*) operator work together?
to_a converts an object to an array when available (Arrays, and many Enumerable objects like Range, Hash, Struct, Enumerator). The splat operator (*) “unarrays” an array (or any object responding to to_a) into a bare list of elements. Common uses:
- Array literals: [*array] spreads elements; [array] nests it.
- Argument passing: method(*args_array) turns an array into positional arguments.
How do I convert strings to numbers, and what’s the strict option?
- Flexible conversions:
- "123".to_i => 123; "1.23".to_f => 1.23
- Non-numeric tails are ignored ("123abc".to_i => 123, "1.2x".to_f => 1.2)
- Non-numeric strings become 0 or 0.0 ("abc".to_i => 0, "abc".to_f => 0.0)
- Strict conversions:
- Integer("123") and Float("1.23") raise ArgumentError if the string isn’t a valid number (e.g., Integer("123x")).
What are to_str and to_ary, and when does Ruby use them?
They’re “role-playing” conversions Ruby uses only when a true String or Array is required:
- to_str: Lets an object behave as a String in string-only contexts (e.g., "Hi " + obj calls obj.to_str).
- to_ary: Lets an object behave as an Array in array-only contexts (e.g., array.concat(obj) calls obj.to_ary).
Implement these only when your object can faithfully act as that core type.
How does truthiness work in Ruby, and what is nil?
Only false and nil are falsy. Everything else is truthy, including 0, "" (empty string), [], and {}.
nil is the sole instance of NilClass, represents “no value,” has falsy Boolean value, and shows up as defaults (e.g., missing array elements). Examples: nil.to_s => "", nil.to_i => 0.
How do object comparisons work: ==, eql?, equal?, and Comparable?
- equal?: Object identity (same object). Don’t redefine it.
- ==: Value equality; usually overridden by classes (e.g., String, Numeric).
- eql?: Often a stricter equality (e.g., 5.eql?(5.0) => false) and used by Hash key comparisons.
- Comparable: Mix in Comparable and define the spaceship operator <=> (return -1, 0, 1) to get <, <=, >, >=, ==, !=, between?, clamp for free.