RSpec自定义匹配器语法。结构上发生了什么?

时间:2016-10-28 16:03:27

标签: ruby

来自RSpec文档:

require 'rspec/expectations'

RSpec::Matchers.define :be_a_multiple_of do |expected|
  match do |actual|
    actual % expected == 0
  end
end

RSpec.describe 9 do
  it { is_expected.to be_a_multiple_of(3) }
end

这里发生了什么?在定义匹配器时,这部分代码是什么:

:be_a_multiple_of do |expected|
      match do |actual|
        actual % expected == 0
      end
    end

那是Proc吗?传递给.define方法的是什么?什么是|expected|?这是我们传入方法的3吗? :be_a_multiple_of如何成为一种方法?似乎有很多元编程魔法正在发生,所以我想弄清楚发生了什么。

这个match do方法是什么?

1 个答案:

答案 0 :(得分:1)

您可以查看初学者的rspec源文档 - http://www.rubydoc.info/gems/rspec-expectations/RSpec/Matchers/DSL/Matcher

如果你想让一个方法可以像这样调用:

some_method :symbol do
end

# one-liner version (parens are needed for arg)
some_method(:symbol) { }

你可以定义:

def some_method(arg, &block)
  # the block gets called in here
end

请参阅Blocks and yields in Ruby

只要将符号转换为方法 - 这实际上非常常见,并且是区分符号和字符串的主要因素之一。

所以在那个RSpec文档页面上,它说:

  

传递给RSpec :: Matchers.define的块将在实例的单例类的上下文中进行计算,并且可以使用宏方法。

如果您想确切了解这里发生了什么,您可以浏览RSpec源代码。然而,内部结构并不一定有文件记载,

请参阅What exactly is the singleton class in ruby?