如何将方法调用存储到Ruby中的数组中,而不是调用它们

如何将方法调用存储到Ruby中的数组中,而不是调用它们,ruby,Ruby,我正在做一个项目,在测试套件中,我们调用一个类中的一组方法 我们必须将它们保留在内存中,但它们在被调用时会停止程序,因此作为一种解决方法,我正在尝试找到一种方法将方法调用推入数组,以便稍后处理它们 现阶段的问题与此类似: def hello(greeting) puts greeting end class Dog hello "Cat" hello "Bear" hello "Snake" hello "

我正在做一个项目,在测试套件中,我们调用一个类中的一组方法
我们必须将它们保留在内存中,但它们在被调用时会停止程序,因此作为一种解决方法,我正在尝试找到一种方法将方法调用推入数组,以便稍后处理它们

现阶段的问题与此类似:

def hello(greeting)
  puts greeting
end

class Dog
  hello "Cat"
  hello "Bear"
  hello "Snake"
  hello "Pig"
  hello "Cow"
  hello "Wolf"
  hello "Lion"

end
问题是:是否有某种方法可以将这些方法调用存储到数组中,以便稍后执行

编辑:

这与我正在处理的代码越接近,类中包含的断言在程序失败时停止程序。我必须在测试套件中保持类不变,所以我不能删除这些断言-但是如果我想在测试套件中测试相同的东西,我不能触发它们。这就是为什么我想找到一种迭代类并将方法调用推送到数组的方法——在测试套件运行之后执行它们。我希望这更清楚一点

我认为这是一个误会。该类不能更改。我正在尝试遍历一个类,以动态遍历已调用的方法的实例


我可以迭代Dog类,并为每个hello编写一个方法吗?

为什么不创建另一个执行所需调用的方法,并在必要时调用该方法?大概是这样的:

def hello(greeting)
  puts greeting
end

class Dog
  def self.sayHello()
    hello "Cat"
    hello "Bear"
    hello "Snake"
    hello "Pig"
    hello "Cow"
    hello "Wolf"
    hello "Lion"
  end
end

# later 

Dog.sayHello()
你所问问题的答案是:

def你好(问候语)
打招呼
结束
你好_targets=%w[猫熊蛇猪牛狼狮子]
lazy_greetings=hello_targets.map do|target|
->{你好(目标)}
结束
#以后,只要你愿意
懒洋洋的问候语[4]。叫“奶牛”
懒散的问候。每个(&:呼叫)
#猫
#忍受
#蛇
#猪
#母牛
#狼
#狮子
然而,我觉得你真正想要的并不是你问的问题

例如,考虑到您发布的示例,没有一个很好的理由像我上面发布的那样去做。下面的代码更简单,并且做同样的事情

你好\u目标=%w[猫熊蛇猪牛狼狮子]
#以后,只要你愿意
你好(args[4])#放‘牛’
hello|u targets.each{| target | hello(target)}
我想找到一种迭代类并将方法调用推送到数组的方法——在测试套件运行后执行它们

如果您想延迟方法调用,您确实可以将其存储在数组中。然后,您可以使用
#send
随时调用它。下面是一个例子:

def a
  puts 'Called a'
end

def b
  puts 'Called b'
end

def c
  puts 'Called c'
end

def d
  puts 'Called d'
end

def my_test
  methods = []
  # assert this, assert that, and
  # if I need to call method a, then
  methods << :a
  # and so on...
  methods << :b
  methods << :c
  methods << :d
end

# Now, to call the methods in the array:

my_test.each { |method| send method }
根据您的代码,您将获得所有动物的列表,一个接一个

相反,如果您想将方法调用存储到一个数组中以供以后调用,则必须找到放置该数组的位置。这很困难:

  • 您无法更改
    Dog
    类,因此无法将其放在那里
  • 您不能将它放在
    hello
    方法中,因为它不会在调用之间保留其值
  • 您不能将它放在另一个类中,然后实例化它,因为您不能将实例传递到
    hello
    ;由于类调用了
    hello
    ,不允许更改类,因此不能修改这些调用以在实例中传递
经过一番修补,我想出了一个解决办法。您需要的是一个为您完成工作的类(此处适当命名为
DogWalker
),实例化为单例实例:

require 'singleton'

def hello(method)
  DogWalker.instance.add_method(method)
end

class DogWalker
  include Singleton

  def initialize
    @methods = []
  end

  def add_method(method)
    @methods << method.downcase.to_sym
  end

  def call_methods
    @methods.each do |m| 
      self.respond_to?(m) ? send(m) : send(:etc)
    end
  end

  def cat
    puts 'called Cat'
  end

  def bear
    puts 'called Bear'
  end

  def snake
    puts 'called Snake'
  end

  def pig
    puts 'called Pig'
  end

  def etc
    puts 'called one of the others'
  end
end

class Dog
  hello "Cat"
  hello "Bear"
  hello "Snake"
  hello "Pig"
  hello "Cow"
  hello "Wolf"
  hello "Lion"
end

Dog

DogWalker.instance.call_methods
require'singleton'
def hello(方法)
DogWalker.instance.add_方法(方法)
结束
走狗班
包括独生子女
def初始化
@方法=[]
结束
def添加_方法(方法)

@方法“但当他们被呼叫时,他们停止了节目”,你能解释更多关于这一点吗?如何停止?错误?您可以使用Procs或lambdas在数组中存储闭包,但您发布的代码示例似乎无法证明这样做的复杂性。存储结果或输入可能更好。该类在我们的测试套件中,“hello”方法实际上是一个assert,因此我面临的困难是使用assert,但在编写测试时试图延迟它。我需要将断言保存在类
SyntaxError
的主体中,当您修复该类时,
nomethoderor
。因为正如OP所提到的,他不允许更改
Dog
类:“我必须在测试套件中保持类不变。”谢谢,这非常有用,我遇到的问题是,我试图按原样迭代类,并存储方法调用,因此,如果该方法被调用4次,它将被推送4次,如果被调用5次,则存储5个方法。@LouisRaymond读了几行之间的内容,我想我明白了你的问题所在,并提出了我认为对你来说是一个解决方案。这太棒了!非常感谢:-)@LouisRaymond不客气。我以前从未找到使用“singleton”的机会,所以我也学到了一些东西。我想,奇怪的代码有它的用途。:)
Dog
require 'singleton'

def hello(method)
  DogWalker.instance.add_method(method)
end

class DogWalker
  include Singleton

  def initialize
    @methods = []
  end

  def add_method(method)
    @methods << method.downcase.to_sym
  end

  def call_methods
    @methods.each do |m| 
      self.respond_to?(m) ? send(m) : send(:etc)
    end
  end

  def cat
    puts 'called Cat'
  end

  def bear
    puts 'called Bear'
  end

  def snake
    puts 'called Snake'
  end

  def pig
    puts 'called Pig'
  end

  def etc
    puts 'called one of the others'
  end
end

class Dog
  hello "Cat"
  hello "Bear"
  hello "Snake"
  hello "Pig"
  hello "Cow"
  hello "Wolf"
  hello "Lion"
end

Dog

DogWalker.instance.call_methods