【问题标题】:Ruby - accessing instance methods / variables from anonymous classRuby - 从匿名类访问实例方法/变量
【发布时间】:2015-03-03 23:11:00
【问题描述】:

我有以下 Ruby 代码:

class Baz
    def foo()
        qux = Class.new() {
            def call()
                bar()
            end
        }.new()
        qux.call()
    end
    def bar()
        puts "bar"
    end
end

b = Baz.new()
b.foo()

如何从匿名类访问方法bar,即从qux.call?有可能吗?

我不断收到这条消息:

classes-test.rb:5:in `call': undefined method `bar' for #<#<Class:0x00000002d9c248>:0x00000002d9c1a8> (NoMethodError)

我是 Ruby 新手,因此我们将不胜感激任何建议甚至更深入的问题解释。提前致谢。

【问题讨论】:

    标签: ruby closures anonymous-class


    【解决方案1】:

    由于.barBaz 的实例方法,因此您需要在上下文中提供Baz 的实例才能调用.bar。您可以通过在初始化时将实例对象传递给类来做到这一点,因此您可以在其上调用其.bar 方法。

    这行得通:

    class Baz
      def foo
        qux = Class.new do
          def initialize(a)  
            @a = a  
          end  
    
          def call
            @a.bar
          end
        end.new(self)
    
        qux.call
      end
    
      def bar
        puts "bar"
      end
    end
    
    b = Baz.new
    b.foo
    => 'bar'
    

    如果您需要将 class 传递给 Class.new(),正如您在 cmets 中提到的那样,您可以像这样重写初始化方法(请注意,您可能必须考虑您的 Closure 类初始化所需的参数 @ 987654331@:

    qux = Class.new(Fiddle::Closure) do
      def initialize(baz)  
        @baz = baz
        super
      end  
    
      def call
        @baz.bar
      end
    end.new(self)
    

    附带说明,您不需要所有这些 (),如果不需要,可以省略它们 Ruby style

    【讨论】:

    • 是否有可能没有构造函数,不知何故?实际上,在实际应用程序中,我需要将它与 Class.new(Fiddle::Closure) 一起使用(要为 C DLL 库创建回调,请参阅 stackoverflow.com/questions/28819592/…)并且在这种情况下重写构造函数不会很舒服。
    • 为什么不呢?您可以重写调用 super 的构造函数以尊重它之前所做的:def initialize(a); @a = a; super; end
    • 如果您实际上不需要实例方法,您可以将其设为类方法,基本上只是一个“函数”,您可以从任何地方调用,而无需先实例化对象。但是实例方法属于对象,您总是需要实例化该类的一个对象,并拥有对它的引用,才能在该特定实例上调用实例方法。这就是实例方法的工作原理。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-15
    • 2021-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多