Jwan622 Jwan622 - 3 months ago 17
Ruby Question

RSpec custom matchers syntax. What is going on structurally?

From the RSpec docs:

require 'rspec/expectations'

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

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

What is going on here? When defining a matcher what is this section of code:

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

Is that a
? What is being passed to the
method? What is
? Is that the 3 that we pass into the method? How does
become a method? There seems to be a lot of metaprogrammy magic going on so I'd like to just figure out what is happening.

What is this
match do


You can look at the rspec source docs for starters - http://www.rubydoc.info/gems/rspec-expectations/RSpec/Matchers/DSL/Matcher

if you wanted to make a method callable like this:

some_method :symbol do

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

you could define this:

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

See Blocks and yields in Ruby

As far as the symbol being turned into a method - this is actually pretty common, and is one of the main things that distinguishes symbols from strings.

So on that RSpec doc page, it says:

The block passed to RSpec::Matchers.define will be evaluated in the context of the singleton class of an instance, and will have the Macros methods available.

If you want to see exactly what's going on here you can go through the RSpec source code. However the internals aren't necessarily as well documented,

See What exactly is the singleton class in ruby?