Defining a Method That Uses a Variable Out of Scope in Ruby

I want to make the Test :: Unit test_helper method, which I can call to erase a bunch of tables after running the tests. Here is a general idea:

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

However, when it teardownworks, I get:

undefined local variable or `models' method

It seems to me that the "def" block does not obey the usual closing rules; I cannot access variables defined outside of his scope.

So, how do I access a variable that is defined outside of the def method declaration?

+3
source share
3 answers

You can do this as a closure with 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.

+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)
+4

Use the class instance variable:

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
+1
source

All Articles