Ruby on rails 在块内定义方法';在Ruby中仍然可以访问全局范围,而不使用块参数?
我想简化一些测试。具体地说,我想定义一个块断言方法,在这个方法中,在块内部您可以访问一个特殊的助手方法,同时还可以访问测试上下文。大概是这样的:Ruby on rails 在块内定义方法';在Ruby中仍然可以访问全局范围,而不使用块参数?,ruby-on-rails,unit-testing,metaprogramming,Ruby On Rails,Unit Testing,Metaprogramming,我想简化一些测试。具体地说,我想定义一个块断言方法,在这个方法中,在块内部您可以访问一个特殊的助手方法,同时还可以访问测试上下文。大概是这样的: def assert_metric(report, metric, &block) def sum(value, *filters) filters.each do |filter| assert_equal value, report.sum(metric, filter) end end instan
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| u context |……
有什么想法吗?您似乎假设
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