在Ruby中,内部类如何访问外部类中定义的变量/方法?

Dan*_*son 0 ruby oop inner-classes fluentd

例子:

require "fluent/plugin/output"

module Fluent::Plugin
    class Outer < Fluent::Plugin::Output
        @outer_var = "Hello from outer variable"

        class Inner
            def initialize()
                puts "@outer_var", @outer_var # nil
                log.info "Hello from inner initialize" # undefined local variable or method log
                outer_method() # undefined method `outer_method' for #<Outer::Inner:0x00007fd2100452b0> (NoMethodError)
            end
        end # Inner

        def initialize()
            Inner.new()
            log.info "Hello from outer initialize" # works
        end

        def outer_method
            puts "Hello from outer method"
        end

    end # Outer
end # Fluent::Plugin
Run Code Online (Sandbox Code Playgroud)

如何使内部类可以访问外部变量和方法?这里的示例显示了如何定义内部/外部类,但没有显示如何访问外部类。我知道 Ruby 中不存在内部/外部类的概念,根据这个答案。在仍然是模块一部分的情况下使用Inner和类的最佳方法是什么?Outeroutput

Jör*_*tag 8

在Ruby中,内部类如何访问外部类中定义的变量/方法?

Ruby 没有“内部”或“外部”类的概念。听起来您好像来自BETA、Scala 或Newspeak 等语言,但Ruby 不是BETA、Scala 或Newspeak。作为一般规则,任何编程语言都完全按照该编程语言的规范所说的方式工作,而不是按照其他编程语言的规范所说的方式工作。BETA、Scala 和 Newspeak 有嵌套类,但 Ruby 没有。

在 Ruby 中,您可以按词法嵌套定义,但这不会创建嵌套类。如果将一个类的定义嵌套在另一个类的定义中,则不会在这两个类之间创建任何类型的关系。没有任何。您无法从另一个类“访问一个类的变量/方法”,因为您可以遵循这两个类来获取这些变量/方法。

嵌套类定义所做的唯一事情是命名空间,即内部类定义到外部类定义的常量。就是这样。两个类之间没有关系,唯一的关系是常量和类之间。

这是不可能的。

在 Ruby 中创建类之间关系的方法是继承,而不是嵌套(因为没有嵌套)。在 Ruby 中创建对象之间关系的方法是关联、聚合或组合,而不是嵌套。

Ruby足够灵活,可以实现一些行为类似于“正确的”BETA 风格内部类的东西。请记住,内部类“嵌套”在外部类的对象实例内。我们可以使用实例变量来模拟:

class Outer
  attr_reader :Inner

  def outer_method
    __callee__
  end

  private

  attr_writer :Inner

  def initialize
    self.Inner = Class.new(self.class) do
      def inner_method
        [__callee__, outer_method]
      end
    end
  end
end

outer = Outer.new
inner = outer.Inner.new
p inner.inner_method
Run Code Online (Sandbox Code Playgroud)

请注意,我让内部类继承外部类:这是在 Ruby 中进行行为共享的方式。你需要有某种形式的继承或关联关系。嵌套不会创建关系。