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

(Tuis.) #1
Object

Numeric Conversions | 71

A::B::C.parent # => A::B
A::B.parent # => A
A.parent # => Object

A::B::C.parents # => [A::B, A, Object]

Numeric Conversions core_ext/numeric/bytes.rb


These methods convert byte expressions, such as45.megabytes, into the equivalent number
of bytes (45.megabytes == 47_185_920). As with numeric conversions to time units, both
singular and plural units are accepted (1.kilobyteor3.kilobytes). Valid units are bytes,
kilobytes, megabytes, gigabytes, terabytes, petabytes, and exabytes.


Object


instance_exec core_ext/object/extending.rb,core_ext/proc.rb


Theinstance_execmethod allows us to evaluate a block in the context of an instance. It is
likeinstance_eval, except it allows arguments to be passed into the block. An implementa-
tion is inobject/extending.rb.


Theinstance_execimplementation uses theProc#bindimplementation fromproc.rb. This
method allowsProcs to be treated likeUnboundMethods; they can be bound to an object and
invoked as methods. The implementation is instructive:
class Proc #:nodoc:
def bind(object)
block, time = self, Time.now
(class << object; self end).class_eval do
methodname = " bind#{time.toi}#{time.usec}"
define_method(method_name, &block)
method = instance_method(method_name)
remove_method(method_name)
method
end.bind(object)
end
end


Theclass_evalblock is evaluated in the context of the object’s singleton class, so the
method created is specific to that object. A method with a (hopefully) unique name is
created, using theProcas the method body. Theinstance_methodmethod grabs the newly
created method object as anUnboundMethodfrom the class. Because we hold a reference to
the method, we can safely remove it from the singleton class usingremove_method, and the
method will remain in existence (anonymously). The last line in theclass_evalreturns
the method from theclass_eval; the method is then bound to the given object and returned.


This definition ofinstance_execis a Ruby 1.8 workaround. In Ruby 1.9,instance_execis a
native method. Also note that this implementation is not threadsafe. It tries to be as safe as
possible, qualifying the method names down to the microsecond and putting them in the
respective objects’ singleton classes, but it will still fail if called twice on the same object
during the same microsecond.

Free download pdf