在每个方法调用之间运行方法

时间:2016-10-30 18:50:55

标签: ruby

基本上我想要这样的东西:

some_method do
  method1()
  method2()
  method3()
end

在这三种方法中的每一种之间,都会有sleep 5,我只是不想在每次方法调用之后重复sleep 5。有没有办法定义some_method,例如,在每个方法调用之间,正在执行像sleep 5这样的特定方法?我不希望在每次方法调用之后插入一堆sleep命令来污染我的代码。

3 个答案:

答案 0 :(得分:2)

如果在示例中,方法不带参数或块,并且未使用返回值,则可以执行以下操作。

module M
  def method1
    puts "method 1"
  end
  def method2
    puts "method 2"
  end
  def method3
    puts "method 3"
  end
end

class A
  include M
  def method4
    puts "method 4"
  end
  def execute_methods
    M.instance_methods.each { |m| send m; sleep 5 }
  end
end

A.new.execute_methods
  # method 1
  # method 2
  # method 3

包含一个包含要执行的方法的模块的一个优点是,您可以在不更改任何其他代码的情况下添加,删除或重命名模块中的方法。此技术可能有用,例如,在执行一系列验证方法时,每个验证方法都返回truefalse

def validate(obj)
  M.instance_methods.all? { |m| send m, obj }
end

这也是具有参数且使用其返回值的方法的示例。

答案 1 :(得分:0)

注意,我不了解Ruby,所以这将是一种javascripty风格的伪代码,并且不会使用任何"特殊功能" Ruby。

这可能是实现您所寻找目标的最简单方法:

function execute_in_sequence(delay, fs) {
    foreach(f in fs) {
        f();
        sleep(delay);
    }
}

然后你就可以使用它:

function p() {
    print(1);
}

execute_in_sequence(500,
    [p, p, p]
);

您还可以使用可变参数函数删除显式列表,这可以让您将其写为:

execute_in_sequence(500,
    p, 
    p, 
    p
);

在此示例中,p非常简单。要使用需要参数的函数执行此操作,您需要首先将调用包装在lambda中。

另请注意,明显的缺陷是您无法以这种方式返回任何值。所有的功能必须通过副作用来运行,这限制了它的使用。

答案 2 :(得分:0)

这是一个可能的some_method实现。 参数是方法名称作为符号(即:method1()的方法1),如果给出了一个块,则在每次方法调用后执行它。

def method1
  puts "Method1"
end

def method2
  puts "Method2"
end

def method3
  puts "Method3"
end

def some_method(*methods)
  methods.each{|m|
    send m
    yield if block_given?
  }
end

some_method(:method1, :method2, :method3) do
  puts "  Waiting 5 sec."
  sleep 5
end

它返回:

Method1
  Waiting 5 sec.
Method2
  Waiting 5 sec.
Method3
  Waiting 5 sec.

通过一些调整和更多逻辑,您还可以将参数发送到不同的方法,并保存方法在数组中返回的内容。