【问题标题】:Reference Method Parameter in Class::new blockClass::new 块中的引用方法参数
【发布时间】:2018-07-24 06:18:13
【问题描述】:

我正在尝试根据以下问题在 Ruby 中使用元编程创建类:Dynamically define named classes in Ruby。一切都很顺利,除了Class.new 的块中似乎无法引用方法参数,这很奇怪。

我有这个

class A; end

module B
  def self.class_with_method(class_name, method_return)
    klass = Class.new(A) do
      def example
        method_return
      end
    end
    B.const_set class_name, klass
  end
end

但是当我有上面的然后用它测试它

B.class_with_method 'ExampleClass', 23
B::ExampleClass.new.example

给我

#<:exampleclass:0x00007ff1d7130d00> (NameError) 的未定义局部变量或方法 `method_return'

这很奇怪,因为如果我要这样做

def add_number(number)
  [1, 2, 3, 4].map {|i| i + number}
end

add_number(2)
# => [3, 4, 5, 6]

很明显,块可以接受方法参数。

有没有办法在块内将method_return 传递给def example

【问题讨论】:

    标签: ruby


    【解决方案1】:

    def 构造关闭了它的作用域。局部变量不能超越这一点。做你想做的事,改用define_method

    【讨论】:

      【解决方案2】:

      由于method_return 是一个变量,因此您不能将其传播到example 方法,除非您在其他上下文中使用它。您可以在类级变量中捕获它:

      klass = Class.new(A) do
        @@method_return = method_return
      
        def example
          @@method_return
        end
      end
      

      您还可以动态定义方法,以便块将method_return 变量捕获为闭包:

      klass = Class.new(A) do
        define_method(:example) do
          method_return
        end
      end
      

      当使用def example 时,块范围会发生变化并变得完全不同。

      【讨论】:

      • 啊,那不是类实例变量,那是类变量!完全不同的东西!
      • @max 我的意思是“类变量的实例”,但也许可以更好地表述。已编辑。
      【解决方案3】:

      这一点也不奇怪,这是方法定义的常规行为:

      class A
        x = 3
        def foo
          x
        end
      end
      
      A.new.foo # NameError: undefined local variable or method `x'
      

      方法定义不会从其外部范围捕获局部变量。这通常很好:通常您不希望方法的结果依赖于其定义时存在的某些随机状态,而是希望它依赖于您调用它的对象!

      当您进行元编程时,当然例外。在这种情况下,捕获局部变量很有用,因此您可以显式使用与其他地方相同的机制来捕获它们:块。

      define_method :example do
        method_return
      end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-09-30
        • 2016-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-05
        • 2016-10-04
        相关资源
        最近更新 更多