在Ruby中对字符串和block求解

http://tech.ddvip.com   2008年01月18日    社区交流

内容摘要:对包含代码的字符串和block求解,是我最钟爱的Ruby特性之一。Ruby提供了多种不同类型的求解方式;不过我最常用的是下面这些:eval、instance_eval和class_eval。

  与使用class_eval的示例类似,实例变量的值可以通过其他的方式获取,不过使用instance_eval是一种非常直观的做法。

  Kernel.eval

  使用Kernel的eval方法可以在当前上下文中对一个字符串求解。可以选择为eval方法制定一个binding对象。如果给定了一个binding对象,求解的过程会在binding对象的上下文中执行。

hello = "hello world"
puts eval("hello") #=> "hello world"
proc = lambda { hello = "goodbye world"; binding }
eval("hello", proc.call) #=> "goodbye world"

  扩展eval的上下文

  第一次使用eval,我用它来创建了attr_init这个类方法。当时我发现我总是在重复下面代码中的模式:

def some_attribute
@some_attribute || = SomeClass.new
end

  因此我决定创建一个类方法来封装上面的行为:

class << Object
def attr_init(name, klass)
define_method(name) { eval "@#{name} ||= #{klass}.new" }
end
end

  记得当时我觉得这样调用eval是非常丑陋的做法,但那会儿我想不出更好的方式来实现这样的效果;因此我把代码贴到了博客中,等待别人的指摘;他们很快就做出了回应,并给出下面的做法。一开始我并没有觉察这样做的好处,但是后来我意识到这个解法是非常出色的:它只需要调用一次eval方法,而不是在每次进行方法定义时都去重新调用eval。

class << Object
def attr_init(name, klass)
eval "define_method(name) { @#{name} ||= #{klass}.new }"
end
end

责编:豆豆技术应用

正在加载评论...