简体   繁体   English

如何在Ruby中调用类的所有实例方法?

[英]How to invoke all instance methods of a class in Ruby?

I'm currently working on throwing together my own little test method runner script. 我目前正在努力将自己的小测试方法运行器脚本放在一起。

I need some way to call all of the methods in a class. 我需要某种方法来调用类中的所有方法。 When I invoke the run_tests method, my program is stuck in an infinite loop. 当我调用run_tests方法时,我的程序陷入了无限循环。 What is causing this and what are some solutions? 是什么原因造成的,有什么解决方案?

class FadTest < SeleniumTest
  def can_open_page
    @driver.get(@base_url + "/")
    wait_element_present(:link, "DOCTORS")
    @driver.find_element(:link, "DOCTORS").click
    puts "page opened"
  end

  def test_method
    puts "it works"
  end

  def run_tests
    klass = self.class
    klass.instance_methods(false).each do |method|
      klass.instance_method(method).bind(self).call
    end
  end 
end

As mentioned by Wand Maker , run_tests involves recursion. 如Wand Maker所述run_tests涉及递归。 Your code is being executed in the following manner: 您的代码通过以下方式执行:

  1. Find the class of some object 查找某个对象的类
  2. Call SomeClass.instance_methods.each {} 调用SomeClass.instance_methods.each {}
  3. Once you reach run_tests , you start the iteration over again. 一旦达到run_tests ,就可以重新开始迭代。
  4. Infinite loop -- you never reach the remaining instance methods. 无限循环-您永远无法达到其余的实例方法。

I am not sure how you have designed your tests, so here are a few options to solve the problem 我不确定您如何设计测试,因此这里有一些解决问题的方法

If all tested objects have the class FadTest , you can edit the logic within the iteration, my preferred solution is what the Tin Man suggested 如果所有测试对象都具有FadTest类,则可以在迭代中编辑逻辑,我的首选解决方案是Tin Man建议的解决方案

klass.instance_methods(false).each do |method|
  next if method == :run_tests
  # ...
end

Only problem is that you are still scanning the :run_tests element. 唯一的问题是您仍在扫描:run_tests元素。 If you want to remain full proof and not have :run_tests in the array, you can try what Cary Swoveland suggested : 如果您想保持完整的证明,而在数组中没有:run_tests ,可以尝试Cary Swoveland的建议

(klass.instance_methods(false) - [:run_tests]).each {}

If the class of the tested object is not FadTest , then I would suggest a rewrite of the method. 如果被测试对象的类不是 FadTest ,那么我建议重写该方法。

def self.run_tests(object)
  klass = object.class
  klass.instance_methods(false).each {}
end

FadTest.run_tests(some_object)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM