这篇文章主要介绍了Ruby元编程技术详解(Ruby Metaprogramming techniques),本文讲解了11个关于元编程的技术和技巧,需要的朋友可以参考下
我最近考虑了很多元编程(Metaprogramming)的问题,并希望看到更多这方面技术的例子和讲解。无论好坏,元编程已经进入Ruby社区,并成为完成各种任务和简化代码的标准方式。既然找不到这类资源,我准备抛砖引玉写一些通用Ruby技术的文章。这些内容可能对从其它语言转向Ruby或者还没有体验到Ruby元编程乐趣的程序员非常有用。
1. 使用单例类 Use the singleton-class
许多操作单个对象的方法是基于操作其单例类(singleton class),并且这样可以使元编程更简单。获得单例类的经典方法是执行如下代码:
sclass = (class << self; self; end)
RCR231建议这样定义Kernel#singleton_class方法:
module Kernel
def singleton_class
class << self; self; end
end
end
我会在下文使用这个方法。
2. DSL的使用类方法来修改子类 Write DSL's using class-methods that rewrite subclasses
当你想创建一个DSL来定义类信息时,最常见的问题是怎样表示信息来让框架的其它部分使用。以定义一个ActiveRecord模型对象为例:
class Product
end
在这个例子中,令人感兴趣的是set_table_name的使用。这是怎么起作用的呢?好吧,这里涉及到一个小魔法。这是一种实现方法:
module ActiveRecord
class Base
def self.set_table_name name
define_attr_method :table_name, name
end
def self.define_attr_method(name, value)
singleton_class.send :alias_method, "original_#{name}", name
singleton_class.class_eval do
define_method(name) do
value
end
end
end
end
end
这里令人感兴趣的是define_attr_method。在这个例子中我们需要获得Product类的单例类,但又不想修改ActiveRecord::Base。通过使用单例类我们达到了这个目的。我们为原来的方法取别名,再定义新的存取器(accessor)来返回值。如果ActiveRecord需要table name就可以直接调用存取器。这种动态创建方法和存取器的技术在单例类是很常见的,特别是Rails。
3. 动态创建class和module Create classes and modules dynamically
Ruby允许你动态创建和修改class和module。你可以在没有冻结的class或module上做任何修改。特定情况下会很有用。Struct类可能是最好的例子:
PersonVO = Struct.new(:name, :phone, :email)
p1 = PersonVO.new(:name => "Ola Bini")
这会创建一个新类,并赋给PersonVO,然后创建一个类的实例。从草稿创建新类并定义新方法也很简单:
c = Class.new
c.class_eval do
define_method :foo do
puts "Hello World"
end
end
c.new.foo # => "Hello World"
除了Struct,还能在SOAP4R和Camping找到轻松创建类的例子。Camping尤其令人感兴趣,因为它有专门的方法创建这些类,被你的controller和view继承。Camping的许多有趣的功能都是用这种方式实现的:
def R(*urls); Class.new(R) { meta_def(:urls) { urls } };
end
这使得可以这样创建controller:
class View
end
end
以上就是Ruby元编程技术详解(Ruby Metaprogramming techniques)的详细内容,更多请关注0133技术站其它相关文章!