Advanced Rails - Building Industrial-Strength Web Apps in Record Time

(Tuis.) #1

24 | Chapter 1: Foundational Techniques


def method_missing(method_id, *args, &block)
...
end

There are several drawbacks to usingmethod_missing:



  • It is slower than conventional method lookup. Simple tests indicate that method
    dispatch withmethod_missingis at least two to three times as expensive in time
    as conventional dispatch.

  • Since the methods being called never actually exist—they are just intercepted at
    the last step of the method lookup process—they cannot be documented or
    introspected as conventional methods can.

  • Because all dynamic methods must go through themethod_missingmethod, the
    body of that method can become quite large if there are many different aspects
    of the code that need to add methods dynamically.

  • Usingmethod_missingrestricts compatibility with future versions of an API.
    Once you rely onmethod_missingto do something interesting with undefined
    methods, introducing new methods in a future API version can break your users’
    expectations.


A good alternative is the approach taken by ActiveRecord’sgenerate_read_methods
feature. Rather than waiting formethod_missingto intercept the calls, ActiveRecord
generates an implementation for the attribute setter and reader methods so that they
can be called via conventional method dispatch.


This is a powerful method in general, and the dynamic nature of Ruby makes it pos-
sible to write methods that replace themselves with optimized versions of them-
selves when they are first called. This is used in Rails routing, which needs to be very
fast; we will see that in action later in this chapter.


Generative Programming: Writing Code On-the-Fly


One powerful technique that encompasses some of the others is generative
programming—code that writes code.


This technique can manifest in the simplest ways, such as writing a shell script to
automate some tedious part of programming. For example, you may want to popu-
late your test fixtures with a sample project for each user:


brad_project:
id: 1
owner_id: 1
billing_status_id: 12

john_project:
id: 2
owner_id: 2
billing_status_id: 4

...
Free download pdf