Ruby define_method,带有基于块的参数

时间:2014-11-13 19:12:12

标签: ruby selenium capybara

我刚想通了,我将我的方法更新到下面并将args传递给块执行:

def self.element(element_name, options = {}, &block)
    define_method "#{element_name}" do |arg=nil|
        find self.instance_exec(*arg, &block), options
    end     
end

BINGOOOO !!!

我的问题如下 -

我有一个方法需要3个参数(method_name,options和& block),这就是我把它放在一起的方法:

def self.element(element_name, options = {}, &block)
    define_method "#{element_name}" do
        find self.instance_exec(&block), options
    end     
end

这就是我调用方法元素的方法:

element(:method_name, visible: 5)  { "#css path to my element" }

现在我在任何地方使用它并执行我想要的任何动作:

method_name.click
...

到目前为止,这一直对我有用,但是当我遇到像下面的例子那样有动态元素的情况时,我需要重复元素发现(有时会重复20次以上):

{ "#csspath1" }
{ "#csspath2" }
{ "#csspath3" }
{ "#csspath4" }
...

我正在块中传递元素路径以完全处理这种情况,但还没有到达那里,我想做的是参数化可重复的数字:

{ |arg| "#csspath#{arg}" }

以某种方式使用define_method创建的方法传递我的块中的参数,因此该方法如下所示:

method(1).click
method(2).click
method(3).click
method(4).click

我还没有到达那里,任何想法都会受到欢迎......

1 个答案:

答案 0 :(得分:1)

这是你想要做的吗? :

def element(element_name, options = {})
  define_method "#{element_name}" do |arg = nil|
    find yield(arg), options
  end     
end

现在定义方法:

element(:method_name, visible: 5) {|num| "#csspath#{num}" }

此处yield语句执行带有默认参数nil的块,在调用时将其转换为字符串时为''(空字符串):

method.click #=> will use "#csspath" for find

如果像这样传递,它将评估和使用参数:

method(1).click #=> will use "#csspath1" instead of "#csspath" for find