Metaid
why the lucky stiff 为Ruby的原编程创建了一个名字为metaid.rb的库。这段小程序可以包含在任何需要原编程的项目里,而且非常有用。
class Object
# The hidden singleton lurks behind everyone
def metaclass; class << self; self; end; end
def meta_eval &blk; metaclass.instance_eval &blk; end
# Adds methods to a metaclass
def meta_def name, &blk
meta_eval { define_method name, &blk }
end
# Defines an instance method within a class
def class_def name, &blk
class_eval { define_method name, &blk }
end
end
上面的库给每一个object定义了四个方法:
metaclass
指向单类的接受者(self).
meta_eval
The equivalent of class_eval for singleton classes. Evaluates the given block in the context of the receiver's singleton class.
meta_def
Defines a method within the receiver's singleton class. If the receiver is a class or module, this will create a class method (instance method of the receiver's singleton class).
class_def
Defines an instance method in the receiver (which must be a class or module).
Metaid's convenience lies in its brevity. By using a shorthand for referring to and augmenting metaclasses, your code will become clearer rather than being littered with constructs like class << self; self; end. The shorter and more readable these techniques are, the more likely you are to use them appropriately in your programs.
This example shows how we can use Metaid to examine and simplify our singleton class hacking:
class Person
def name; "Bob"; end
def self.species; "Homo sapiens"; end
end
Class methods are added as instance methods of the singleton class:
Person.instance_methods(false) # => ["name"]
Person.metaclass.instance_methods -
Object.metaclass.instance_methods # => ["species"]
Using the methods from Metaid, we could have written the method definitions as:
Person.class_def(:name) { "Bob" }
Person.meta_def(:species) { "Homo sapiens" }