【问题标题】:Defining a method that uses an out-of-scope variable in Ruby在 Ruby 中定义使用范围外变量的方法
【发布时间】:2011-08-21 18:55:56
【问题描述】:

我想创建一个 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”方法声明之外定义的变量?

【问题讨论】:

    标签: ruby metaprogramming closures


    【解决方案1】:

    您可以使用 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】:

      方法定义在 Ruby 中不是闭包。 classmoduledefend 关键字都是范围门。为了跨范围门保持范围,您必须通过一个块;块是闭包,因此在定义它们的范围内运行。

      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)
      

      【讨论】:

      • ...不幸的是,我不能这样做,因为对拆卸的调用不受我的控制。 :-\我很害怕这个,但谢谢你的确认。
      【解决方案3】:

      使用类实例变量:

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-08-18
        • 2011-02-01
        • 2016-01-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多