Try `BasicObject.new.methods` and you get a `NoMethodError`: unlike an ordinary `Object.new`, a basic object has no `methods` method. Even `p BasicObject.new` fails because the instance lacks `inspect`. BasicObject is Ruby’s nearly blank-slate class, intended for objects that need very little behavior of their own. section 2.3 section 3.5.3 section 13.3
BasicObject sits above Object at the top of the usual class ancestry chain. A new BasicObject instance has fewer than ten instance methods, compared with roughly sixty on a new Object instance; the counts can vary by Ruby release. To inspect that small method set, ask the class with `BasicObject.instance_methods(false)`, rather than asking an instance to list its methods. section 3.5.3 section 13.3
Why start with so little? Method lookup can climb through a class’s ancestors as far as BasicObject. Ordinary objects also gain many familiar methods through Object and its included Kernel module. Those inherited names may accidentally intercept a message that a domain-specific object meant to interpret itself. Subclassing BasicObject reduces such clashes; defining `method_missing` then lets the object assign meaning to messages it does not recognize. section 4.2.1 section 13.3.1
Turning calls into an indented list
A `Lister < BasicObject` can treat each missing method name as a list heading. Its `method_missing` appends the name, increases an indentation counter, yields to a supplied block for nested entries, then decreases the counter. Calls named `freeze`, `inspect`, `sleep`, and `print` can therefore become headings instead of invoking familiar object methods. This works precisely because a BasicObject instance does not already recognize those names. section 13.3.2
Listing 13.2 Lister class: Generating indented lists from a BasicObject subclass
class Lister < BasicObject
attr_reader :list
def initialize 1
@list = ""
@level = 0
end
def indent(string) 2
" " * @level + string.to_s
end
def method_missing(m, &block) 3
@list << indent(m) + ":" 4
@list << "\n"
@level += 2 5
@list << indent(yield(self)) if block 6
@level -= 2
@list << "\n"
return "" 7
end
end
The complete Lister implementation shows how `method_missing` accumulates output and uses a block to control indentation. section 13.3.2
The blank slate has costs. Lister checks whether its captured block is present instead of calling `block_given?`, which BasicObject instances lack. It also returns an empty string from `method_missing` so nested calls do not append the accumulating list to itself. A larger example is the Builder XML-writing library: it turns missing method calls into XML tags, with blocks expressing nesting. BasicObject is useful for this kind of deliberately controlled message vocabulary, not something most classes need to inherit from. section 13.3.2 section 13.3.1 section 3.5.3
