Определить метод в области видимости блока, все еще имея доступ к глобальной области видимости в Ruby, без аргументов блока? - PullRequest
0 голосов
/ 21 марта 2011

Я хочу упростить некоторые тесты.В частности, я хочу определить метод подтверждения блока, где внутри блока у вас есть доступ к специальному вспомогательному методу, но при этом также есть доступ к контексту теста.Примерно так:

def assert_metric(report, metric, &block)
  def sum(value, *filters)
    filters.each do |filter|
      assert_equal value, report.sum(metric, filter)
    end
  end
  instance_eval(&block)
end

assert_metric report, :select_count do
  sum 1
  sum 1, :bookmark, :like
  sum 0, :vote
end

Как правильно это сделать?

Ограничения *:

  • sum В текущем выполняющемся методе выполняетсяконтекст теста (чтобы вы могли сделать assert_equal и получить доступ ко всем переменным экземпляра.
  • sum недоступен вне этого блока
  • Вы не можете получить аргумент блока (т. е. do |test_context|...)

Есть идеи?

1 Ответ

1 голос
/ 21 марта 2011

Похоже, вы предполагаете, что def sum работает как вложенная функция в Python. Это не так. Это определит метод в вашем тестовом классе. Нет способа определить метод только внутри другого метода - методы принадлежат классам или объектам. Однако вы можете определить объект, который существует только там, который реализует метод.

Если я правильно понимаю ваши требования, ближайший эквивалент будет выглядеть примерно так:

require 'delegate'

def assert_metric(report, metric, &block)
  ctx = SimpleDelegator.new(self)
  ctx.singleton_class.class_eval do
    define_method(:sum) do
      filters.each {|filter| assert_equal value, report.sum(metric, filter)}
    end
  end
  ctx.instance_eval(&block)
end
...