第二段代码会收集嵌套在模块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