Ruby 访问模块实例变量

Ruby 访问模块实例变量,ruby,module,Ruby,Module,我试图访问模块方法中的实例变量 module Filter def self.included(target) puts "INCLUDED: #{@var}" target.instance_variable_set(:@var, @var) # doesn't seem to work end def self.var=(var) @var = var end def self.var @var end def hello

我试图访问模块方法中的实例变量

module Filter
  def self.included(target)
    puts "INCLUDED: #{@var}"
    target.instance_variable_set(:@var, @var) # doesn't seem to work
  end

  def self.var=(var)
    @var = var
  end

  def self.var
    @var
  end

  def hello
    @var
  end

end

f = Filter
f.var = "hello"

puts "SET: #{f.var}"

class Main
  include Filter
end

m = Main.new

puts "HELLO: #{m.hello}"
它产生以下输出:

ruby test2.rb
SET: hello
INCLUDED: hello
HELLO: 

最后一行“HELLO:”需要输出“HELLO:HELLO”。如何初始化@var实例变量以实现这一点?

与许多其他变量一样,您也被术语“实例变量”弄糊涂了。它是一个实例变量,好吧,但它不是你想的一个实例

记住,ruby中的一切都是对象。甚至班级本身

  def self.included(target)
    puts "INCLUDED: #{@var}"
    target.instance_variable_set(:@var, @var) # doesn't seem to work
  end
在这里,您将实例变量设置为
target
(很可能是
)。然而,您正试图从
target
的实例中读取数据

m = Main.new

puts "HELLO: #{m.hello}"
这就是变量的位置:

puts "The right HELLO: #{Main.instance_variable_get(:@var)}"

当然,不可能(以这种方式)在尚不存在的实例上设置实例变量!根据您的具体目标,可以实施不同的策略。我建议你再问一个更精致的问题。

谢谢,是的,有点让人困惑。我只需要在调用m.hello时能够访问@var,这是模块中包含的方法。有什么想法吗?@Vidar:这是一个选项-
def hello;self.class.instance_variable_get(:@var);尽管如此,还是要小心。如果更改该
@var
,则
target
的所有实例都将看到更新版本。不确定这是否是你想要的行为。那么我该如何避免呢?这正是我不想做的。我在(@@var)之前使用了一个类变量,得到了一个竞争条件。这是另一个问题。集中注意力。