【问题标题】:How to access instance variable of a module from abother module?如何从另一个模块访问模块的实例变量?
【发布时间】:2016-05-15 16:02:47
【问题描述】:

我有模块

module SomeModule
  @param = 'Hello'
end

module Reporter
  include SomeModule
  def self.put
    puts @param
  end
end

当我调用Reporter::put 时没有输出,我想Reporter 模块无法访问实例变量@param。有什么方法可以从Reporter 模块访问该变量?

【问题讨论】:

  • self.put 是一个类级别的方法。你希望它如何访问实例变量?
  • 你说得对,我在想什么??

标签: ruby module


【解决方案1】:

你可以使用类变量代替实例变量

module SomeModule
  @@param = 'Hello'
end

module Reporter
 include SomeModule
 def self.put
  puts @@param
 end
end

Reporter.put 打印 123 并在这种情况下返回 nil

【讨论】:

    【解决方案2】:

    是的。

    SomeModule.instance_variable_get(:@param)
    

    【讨论】:

      【解决方案3】:

      实例变量称为实例变量,因为它们属于对象(又名“实例”)。您的示例中有两个对象:SomeModuleReporter。两者都有自己的实例变量。 SomeModule 有一个名为 @param 的实例变量,Reporter 有一个名为 @param 的实例变量。这两个实例变量完全不相关,即使它们具有相同的名称。想象一下,如果每个对象都必须为实例变量提供自己的名称,那会是多么混乱!

      有没有办法从Reporter 模块访问该变量?

      没有。您不能从不同的对象访问实例变量。一个对象只能访问其自己的实例变量。

      [注意:当然可以使用反射(例如Object#instance_variable_getBasicObject#instance_evalBasicObject#instance_exec)。使用反射可以做很多事情。]

      但是,您可以做的是创建一个方法,让您可以读取该实例变量。这种方法称为属性读取器

      module SomeModule
        def self.param; @param end
        @param = 'Hello'
      end
      
      module Reporter
        def self.put
          puts SomeModule.param
        end
      end
      

      甚至还有一种方法可以自动为你生成这样的方法,叫做Module#attr_reader

      module SomeModule
        class << self; attr_reader :param end
        @param = 'Hello'
      end
      
      module Reporter
        def self.put
          puts SomeModule.param
        end
      end
      

      如果还想写入实例变量,还需要定义一个对应的属性写入器方法:

      module SomeModule
        class << self
          attr_reader :param
      
          private
      
          def param=(param)
            @param = param
          end
        end
      
        self.param = 'Hello'
      end
      
      module Reporter
        def self.put
          puts SomeModule.param
        end
      end
      

      还有一个对应的方法叫做Module#attr_writer,它会为你生成一个属性写入器方法:

      module SomeModule
        class << self
          attr_reader :param
      
          private
      
          attr_writer :param
        end
      
        self.param = 'Hello'
      end
      
      module Reporter
        def self.put
          puts SomeModule.param
        end
      end
      

      【讨论】:

      • 非常感谢您提供这些信息,这对我来说非常有意义
      猜你喜欢
      • 2020-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-01
      • 2021-02-13
      • 2012-12-10
      相关资源
      最近更新 更多