chapter fifteen

15 Callbacks, hooks, and runtime introspection

 

This chapter covers

  • Runtime callbacks: inherited, included, and more
  • The respond_to? and method_missing methods
  • Introspection of object and class-method lists
  • Trapping unresolved constant references
  • Examining in-scope variables and constants
  • Parsing caller and stack trace information

In keeping with its dynamic nature and its encouragement of flexible, supple object and program design, Ruby provides a large number of ways to examine what’s going on while your program is running and to set up event-based callbacks and hooks—essentially, tripwires that are pulled at specified times and for specific reasons—in the form of methods with special, reserved names for which you can, if you wish, provide definitions. Thus you can rig a module so that a particular method gets called every time a class includes that module, or write a callback method for a class that gets called every time the class is inherited, and so on.

In addition to runtime callbacks, Ruby lets you perform more passive but often critical acts of examination: you can ask objects what methods they can execute (in even more ways than you’ve seen already) or what instance variables they have. You can query classes and modules for their constants and their instance methods.

15.1 Callbacks and hooks

15.1.1 Intercepting unrecognized messages with method_missing

15.1.2 Trapping include and prepend operations

15.1.3 Intercepting extend

15.1.4 Intercepting inheritance with Class#inherited

15.1.5 The Module#const_missing method

15.1.6 The method_added and singleton_method_added methods

15.2 Interpreting object capability queries

15.2.1 Listing an object’s non-private methods

15.2.2 Listing private and protected methods

15.2.3 Getting class and module instance methods

15.2.4 Listing objects’ singleton methods

15.3 Introspection of variables and constants

15.3.1 Listing local and global variables

15.3.2 Listing instance variables

15.4 Tracing execution

15.4.1 Examining the stack trace with caller

15.4.2 Writing a tool for parsing stack traces

15.5 Callbacks and method inspection in practice

15.5.1 MicroTest background: MiniTest

15.5.2 Specifying and implementing MicroTest

15.6 Summary