liveBook · Manning

Callback

As explained in The Well-Grounded Rubyist, Fourth Edition

A callback is a method or function that a runtime invokes automatically in response to a specified event or lifecycle operation.

A Ruby callback is a specially named method that Ruby calls when a particular runtime event occurs. Define the method on the relevant object, class, or module to react to that event; callbacks are not global tripwires. For example, a module can react when it is included, while a class can react when it is subclassed. section 15.1

The callback name determines which event it catches:

  • `included` and `prepended` receive the class or module performing the operation. `extended` receives the object being extended. section 15.1.2 section 15.1.3
  • `inherited` receives the new subclass. A subclass can itself trigger the inherited callback when subclassed. section 15.1.4
  • `const_missing` runs when a constant cannot be found; it can define that constant so later references find it normally. section 15.1.5
  • `method_added` runs when an instance method is defined or redefined. `singleton_method_added` watches singleton methods—and can run when it is itself defined. section 15.1.6

Callback events follow the operation performed, not just its eventual effect. Extending an object with a module and including that module in the object's singleton class both add it to the object's method-lookup path, but the former triggers `extended` and the latter `included`. Likewise, subclassing does not trigger an `inherited` callback on the superclass's singleton class. section 15.1.3 section 15.1.4

Add class behavior during inclusion

Define `self.included(cl)` on a module to add a class method to `cl` when the module is included. The module's ordinary instance methods become available to instances; the callback supplies behavior to the class object itself. section 15.1.2

Listing 15.1 Using included to add a class method as part of a mix-in operation
module M
  def self.included(cl)
    def cl.a_class_method
      puts "Now the class has a new class method."
    end
  end
  def an_inst_method
    puts "This module supplies this instance method."
  end
end
class C
  include M
end
C.a_class_method
c = C.new
c.an_inst_method

The `included` callback defines `a_class_method` on the receiving class, alongside the instance method supplied by the module. section 15.1.2

`method_missing` is a related hook for an unrecognized message. It can forward a call to another object, including its arguments and block, or handle selected method names and pass the rest to `super`. If it makes new messages usable, `respond_to_missing?` can make capability checks agree with that behavior. section 15.1.1

Run tests as methods are defined

A small test utility uses `inherited` to install `method_added` on each new test subclass. When a method whose name starts with `test` is defined, the callback creates an instance, runs `setup` if present, and calls the test. This design runs tests in definition order, so `setup` must be defined first. section 15.5.2

How The Well-Grounded Rubyist, Fourth Edition covers it

How deep it goes
Works through callback arguments, triggering behavior, singleton-class contrasts, and a small test runner rather than presenting an exhaustive API reference.
Examples
Demonstrates inclusion adding a class method, extension reporting its receiver, and test methods executing when defined.
What it assumes
Assumes familiarity with Ruby modules, classes, method lookup, and singleton methods while explaining the callback events they can trigger.
What you can do after
Build it from scratch: combine `inherited` and `method_added` to run setup and test methods as they are defined.
How it connects
Connects callbacks to method lookup, modules, inheritance, singleton classes, and runtime introspection.

Also explained in

Compare how 19 books explain callback →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of The Well-Grounded Rubyist, Fourth Edition. The section links point to the parts of the book it draws on.