在Ruby中对字符串和block求解

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

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

tables.concat([:table1])

  此句只是将所有的表名加入到tables数组中,并且可以被内部的block访问。有了这一行代码的处理,我们就可以让子查询产生正确的结果了。

delete from table1 where exists (select column2 from table2 where table1.column1 = table2.column2)

  下面的代码可以产生上述结果,并且能够作为参考,以了解如何与binding一起使用eval。

class Delete
def self.from
Delete.new
end
def [](*args)
@text = "delete from "
@text += args.join ","
@tables = args
self
end
attr_reader :tables
def where(&block)
@text += " where "
instance_eval &block
end
def exists(statement)
@text += "exists "
@text += statement
end
end
class Select
def self.[](*args)
self.new(*args)
end
def initialize(*columns)
@text = "select "
@text += columns.join ","
end
def from
@text += " from "
self
end
def [](*args)
@text += args.join ","
@tables = args
self
end
def tables
@tables
end
def where(&block)
@text += " where "
tables.concat(eval("respond_to?(:tables) ? tables : []", block.binding)).inspect
instance_eval &block
end
def method_missing(sym, *args)
super unless @tables.include? sym
klass = Class.new
klass.class_eval do
def initialize(table)
@table = table
end
def method_missing(sym, *args)
@table.to_s + "." + sym.to_s
end
end
klass.new(sym)
end
def equal(*args)
@text += args.join "="
end
end

  结语

  正如我们所看到的那样,使用Ruby提供的多种求解方法,我们可以创建简练、可读的代码;这些求解方法同时提供了创建诸如领域特定语言之类强大工具的能力。

  关于作者

  Jay Fields是ThoughtWorks的一位开发人员。他总是在寻找令人兴奋的新技术,并愿意马上采用这些技术。他最近一段时间的工作中心放在领域特定语言(DSL)上面,所交付的应用为特定业务领域专家使用DSL撰写应用业务规则提供了强大的支持。

责编:豆豆技术应用

正在加载评论...