Ruby метапрограммирование, как RSpec 'должен' работать? - PullRequest
13 голосов
/ 24 июня 2010

Я читал о RSpec и пытался выяснить, как реализовано RSpec «следует».

Может ли кто-нибудь подсказать, как работает мета-природа этой функции?

Код находится здесь:

http://github.com/dchelimsky/rspec/blob/master/lib/spec/expectations/extensions/kernel.rb

ТИА,

-daniel

Уточнение:

target.should == 5

Каким образом значение цели передавалось в «следует», что в свою очередь было «==» против 5?

1 Ответ

27 голосов
/ 25 июня 2010

Взгляните на класс OperatorMatcher .

Все сводится к Ruby, что позволяет вам исключить точки и скобки.На самом деле вы пишете:

target.should.send(:==, 5)

То есть отправьте сообщение should объекту target, а затем отправьте сообщение == на то, что should возвращает.

Метод should - это обезьяна, исправленная в Kernel, поэтому он может быть получен любым объектом.Matcher, возвращаемый should, содержит actual, который в данном случае равен target.

В Matcher реализован метод ==, который сравнивает с expected, в данном случае номером 5. Сокращенный пример, который вы можете попробовать сами:

module Kernel
  def should
    Matcher.new(self)
  end
end

class Matcher
  def initialize(actual)
    @actual = actual
  end

  def == expected
    if @actual == expected
      puts "Hurrah!"
    else
      puts "Booo!"
    end
  end
end

target = 4
target.should == 5
=> Booo!

target = 5
target.should == 5
=> Hurrah!
...