第二段ruby代码的作用是,遍历ruby文件dsl_capybara.rb、dsl_sikuli.rb、dsl_restful.rb及dsl_savon.rb,这些被遍历的文件的共同点是,在模块DSLSet中都分别地定义了一个独有的模块,这些独有的模块中分别定义了一些公有的类方法,如第一段代码所示,注意,各个独有模块所定义的公有的类方法的方法名可能相同,同时,参数也可能相同。
第二段代码会收集嵌套在模块DSLSet中的模块(分布于文件dsl_capybara.rb、dsl_sikuli.rb、dsl_restful.rb及dsl_savon.rb中)所定义的公有类方法,然后,自动在模块DSLSet中直接定义同名的公有的类方法,调用这些类方法时都需要额外地提供一个参数:driver用于选择具体使用嵌套在模块DSLSet中的哪一个模块,然后,自动生成的直接定义在模块DSLSet中的公有的类方法将根据参数:driver的取值不同,去调用相应的子模块的公有的类方法。
总之,第二段代码的作用就是自动生成代码,用于为其他文件中定义的模块的类方法提供一个统一的分发接口。
-
module DSLSet
-
module DSLCapybara
-
require 'capybara'
-
require 'capybara/dsl'
-
require 'capybara/rspec/matchers'
-
-
extend Capybara::DSL # include keywords defined in Capybara::DSL
-
-
## override capybara methods or add new methods
-
class << self
-
def keyword1 # any kind of parameters combination
-
#something, maybe 'yield'
-
helper
-
#something, maybe 'yield'
-
end
-
-
def keyword2 # any kind of parameters combination
-
#something, maybe 'yield'
-
end
-
-
private
-
def helper
-
# something
-
end
-
end
-
end
-
require File.join(File.dirname(__FILE__), 'dsl_capybara.rb')
-
require File.join(File.dirname(__FILE__), 'dsl_sikuli.rb')
-
require File.join(File.dirname(__FILE__), 'dsl_restful.rb')
-
require File.join(File.dirname(__FILE__), 'dsl_savon.rb')
-
-
module DSLSet
-
def default_driver
-
@@default_driver
-
end
-
-
def set_default_driver driver
-
driver = "DSL#{driver.capitalize}" unless driver =~ /^DSL/
-
if @@dsl_set.keys.include?(driver.to_sym)
-
@@default_driver = driver if (driver != @@default_driver)
-
else
-
puts "Invalid parameter: #{driver}"
-
end
-
end
-
-
class << self
-
-
def key_words
-
@@dsl_set.values.flatten.uniq
-
end
-
-
def drivers
-
ds = {}
-
-
@@dsl_set.each do |key, value|
-
ds[key] = {}
-
dm = DSLSet.module_eval(key.to_s)
-
value.each do |v|
-
ds[key][v] = dm.public_method(v).parameters
-
end
-
end
-
-
ds
-
end
-
-
def init
-
@@default_driver = "" # "DSLCapybara"
-
@@dsl_set = {}
-
DSLSet.constants.collect do |cnst_name|
-
m = DSLSet.const_get(cnst_name)
-
@@dsl_set[cnst_name] = []
-
dm = DSLSet.module_eval(cnst_name.to_s)
-
dm.singleton_methods.each do |k|
-
@@dsl_set[cnst_name] << k
-
end
-
end
-
key_words.each do |kw|
-
define_method(kw) do |*args, &block|
-
driver = @@default_driver
-
ps = []
-
args.each_with_index do |arg, idx|
-
if arg.is_a?(Hash) and arg.keys.include?(:driver)
-
driver = arg[:driver]
-
th = arg.dup
-
th.delete :driver
-
ps << th unless th.empty?
-
ps += args[(idx+1)..-1]
-
break
-
else
-
ps << arg
-
end
-
end
-
-
driver = "DSL#{driver.capitalize}" unless driver =~ /^DSL/
-
unless driver and @@dsl_set.keys.include?(driver.to_sym)
-
puts "You are setting #{driver} as driver, which is not valid."
-
puts "Please choose a driver from #{@@dsl_set.keys.to_s}"
-
raise "You are setting #{driver} as driver, which is not valid. Please choose a driver from #{@@dsl_set.keys.to_s}"
-
end
-
-
if @@dsl_set[driver.to_sym] and @@dsl_set[driver.to_sym].include?(kw)
-
mtd = DSLSet.module_eval(driver).public_method(kw)
-
begin
-
mtd.call(*ps, &block)
-
rescue ArgumentError=>e
-
puts "="*50
-
puts e.to_s
-
puts "method \"#{kw}\" of driver \"#{driver}\" was called"
-
puts "expected parameter is #{mtd.parameters.to_s}"
-
puts "actual parameters input are " + ps.to_s
-
project_dir = File.expand_path(File.join(File.expand_path(__FILE__), '..\..'))
-
pd = Regexp.new("^#{project_dir}")
-
e.backtrace.each {|line| puts line if line=~pd}
-
puts "="*50
-
end
-
else
-
raise "#### driver \"#{driver}\" doesn't exist or it has not method \"#{kw}\" ####"
-
end
-
end
-
end
-
end
-
end
-
end
-
-
DSLSet.init
-
include DSLSet
-
-
# if __FILE__
-
# puts "\n\n"
-
# puts DSLSet.drivers
-
# puts "\n\n"
-
# puts DSLSet.key_words.sort
-
# puts "\n\n"
-
# end
阅读(2248) | 评论(0) | 转发(0) |