【问题标题】:define method inside block在块内定义方法
【发布时间】:2014-03-02 00:15:58
【问题描述】:

我是 ruby​​ 新手,我正在通过 RSpec 编写 unittest 来学习 ruby​​,在定义自定义匹配器时,RSpec 中有一行代码我无法理解。

RSpec::Matchers.define :be_a_multiple_of do |expected|
  match do |actual|
    do_the_math(actual, expected)
  end

  def do_the_math(actual, expected)
    actual % expected == 0
  end
end

据我所知,ruby 是一种脚本语言,编译器会按顺序读取代码。也就是说,您必须在使用它之前定义该方法。但是在 RSpec 中,当我定义一个自定义匹配器时,我可以在调用它之后定义辅助方法。

我已经编写了测试代码来测试如果我在定义它之前调用该方法它将失败的事实,并且我还从 RSpec 中读取了一些源代码,define 方法实际上是 define_method 的包装器并将委托传递为堵塞。但我仍然无法理解这段代码是如何工作的。

有人可以帮帮我吗?只是简单解释一下这是如何工作的

【问题讨论】:

    标签: ruby rspec


    【解决方案1】:

    简短的解释是:你还没有在里面调用这个方法,你只是说当你调用be_a_multiple_of匹配器时调用它,并且在发生这种情况时该方法已经定义。

    在声明方法或块时,解析器不会检查方法是否已定义 - 因为该方法可能稍后定义,或者可能存在 missing_methodfall_back。

    【讨论】:

    • 感谢您的帮助,是的,我知道在调用 be_a_multiple_of 之前会调用外部块,但是该块仍然是按顺序执行的不是吗?那是因为missing_method 在手头工作吗?或者可能 match 是一个异步方法,并且在定义 do_match_math 之后将调用该块?
    • 它确实按顺序读取它,而不是执行它们。 Rspec::Matcher.define 方法抓取块并将其存储在实例变量中以供以后使用 - 它在需要之前不会执行它。
    • "方法抓取块并将其存储在实例变量中以备后用" 对,就是这样,感谢您的帮助,答案让我很高兴
    • 实际上这就是我使用的版本。最新版本显然采用了该块并将其转换为使用 define_method 方法的方法。结果是一样的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多