我想创建一个Test :: Unit test_helper方法,我可以在测试执行后调用它来擦除一堆表。这是我的一般想法:
def self.wipe_models(*models)
def teardown
models.each do |model|
model = model.to_s.camelize.constantize
model.connection.execute "delete from #{model.table_name}"
end
end
end
然而,当teardown
运行时,我得到:
未定义的局部变量或方法`models'
对我来说,看起来“def”区块不遵守关闭的通常规则;我无法访问在其范围之外定义的变量。
那么,如何访问在“def”方法声明之外定义的变量?
答案 0 :(得分:4)
方法定义不是Ruby中的闭包。 class
,module
,def
和end
关键字都是范围门。为了保持范围门的范围,你必须通过一个块;块是闭包,因此在它们被定义的范围内运行。
def foo
# since we're in a different scope than the one the block is defined in,
# setting x here will not affect the result of the yield
x = 900
puts yield #=> outputs "16"
end
# x and the block passed to Proc.new have the same scope
x = 4
square_x = Proc.new { x * x }
foo(&square_x)
答案 1 :(得分:4)
您可以使用define_method
:
def self.wipe_models(*models)
define_method(:teardown) do
models.each do |model|
model = model.to_s.camelize.constantize
model.connection.execute "delete from #{model.table_name}"
end
end
end
现在方法体是一个块,可以访问models
。
答案 2 :(得分:1)
使用类实例变量:
cattr_accessor :models_to_wipe
def self.wipe_models(*models)
self.models_to_wipe = models
end
def teardown
self.class.models_to_wipe.each do |model|
model = model.to_s.camelize.constantize
model.connection.execute "delete from #{model.table_name}"
end
end