Dynamically Creating Methods

One important metaprogramming technique is the use of methods that create methods. The attr_reader and attr_accessor methods (see Accessors and Attributes) are examples. These private instance methods of Module are used like keywords within class definitions. They accept attribute names as their arguments, and dynamically create methods with those names. The examples that follow are variants on these attribute accessor creation methods and demonstrate two different ways to dynamically create methods like this.

Defining Methods with class_eval

Example 8-6defines private instance methods of Module named readonly and readwrite. These methods work like attr_reader and attr_accessor do, and they are here to demonstrate how those methods are implemented. The implementation is actually quite simple: readonly and readwrite first build a string of Ruby code containing the def statements required to define appropriate accessor methods. Next, they evaluate that string of code using class_eval (described earlier in the chapter). Using class_eval like this incurs the slight overhead of parsing the string of code. The benefit, however, is that the methods we define need not use any reflective APIs themselves; they can query or set the value of an instance variable directly.

Example 8-6. Attribute methods with class_eval

class Module private # The methods that follow are both private # This method works like attr_reader, but has a shorter name def readonly(*syms) return ...

Get The Ruby Programming Language now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.