Ruby 是当前用于建立内部 DSL 最流行的语言。当在 Ruby 上开发时你所考虑的大部分基础设施都是基于 DSL 的例如:Active Record、RSpec、Cucumber、Rake 以及许多其他方面,— 因为它是服从于主机托管内部 DSL 的。行为驱动开发 (BDD) 的新潮技术需要一个强大的 DSL 基础来实现其普及。Rails DSL很大程度上依赖于Ruby的元编程能力,这里将对Ruby的 DSL 写一个简单测试的例子,功能如下:
##首先给出测试脚本,新建test.txt文件:
host "www.baidu.com"
port 80
page "s"
field "wd","everyday-cn"
field "sourceid","Mozilla-search"
get
check_content "tang.jilong"
check_content "Tim.Tang"
##编写ruby dsl文件:
require 'open-uri'
class MyDSL
def self.dsl_accessor(*symbols)
symbols.each { |sym|
class_eval %{
def #{sym}(*val)
if val.empty?
@#{sym}
else
@#{sym} = val.size == 1 ? val[0] : val
end
end
}
}
end
def method_missing(sym, *args)
self.class.dsl_accessor sym
puts "method missing #{sym}, #{args}"
send(sym, *args)
end
attr_accessor :query
dsl_accessor :test
def self.load(filename)
dsl = new
dsl.instance_eval(File.read(filename), filename)
puts File.read(filename)
dsl
end
def self.loads(filename)
dsl = new
dsl.instance_eval(filename)
dsl
end
def field(field_string,value)
puts "#{field_string}=#{value}"
if ! @query
@query="#{field_string}=#{value}"
else
@query="#{@query}&#{field_string}=#{value}"
end
puts @query
end
def get
puts 'get'
@request="http://#{@host}:#{@port}/#{@page}?#{@query}"
puts @request
@result=open(@request)
end
def check_content(s)
tmp=@result.read.scan(s).uniq
if tmp.length!=0
puts "found"
puts tmp
else
puts "not found"
end
end
def post
puts 'post'
end
end
dsl=MyDSL.load("dsl.txt")
p dsl
p dsl.instance_variables
##其中method_missing和dsl_accessor让客户端动态增删属性的功能
13 December 2011 Suzhou, China目前ruby dsl还主要用在测试领域,将来的发展潜力巨大。