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

(Tuis.) #1
Examples | 41

That way, we have a smallEnumeratorobject whoseeachmethod behaves just as
hash’seach_valuemethod does. This is preferable to creating a potentially large array
and releasing it moments later. In Ruby 1.9, this is the default behavior if the iterator
is not given a block. This simplifies our code:


hash.each_value.map{|value| ... }

Examples


Runtime Feature Changes


This example ties together several of the techniques we have seen in this chapter. We
return to thePerson example, where we want to time several expensive methods:


class Person
def refresh
#...
end

def dup
#...
end
end

In order to deploy this to a production environment, we may not want to leave our
timing code in place all of the time because of overhead. However, we probably want
to have the option to enable it when debugging. We will develop code that allows us
to add and remove features (in this case, timing code) at runtime without touching
the original source.


First, we set up methods wrapping each of our expensive methods with timing com-
mands. As usual, we do this by monkeypatching the timing methods intoPerson
from another file to separate the timing code from the actual model logic:*


class Person
TIMED_METHODS = [:refresh, :dup]
TIMED_METHODS.each do |method|
# set up _without_timing alias of original method
alias_method :"#{method}_without_timing", method

# set up _with_timing method that wraps the original in timing code
define_method :"#{method}_with_timing" do
start_time = Time.now.to_f
returning(self.send(:"#{method}_without_timing")) do
end_time = Time.now.to_f


  • This code sample uses variable interpolation inside a symbol literal. Because the symbol is defined using a
    double-quoted string, variable interpolation is just as valid as in any other double-quoted string: the sym-
    bol:"sym#{2+2}" is the same symbol as:sym4.

Free download pdf