Ruby:扩展实例变量

时间:2016-10-23 00:41:35

标签: ruby

如何在extend实例时设置一些实例变量,方法与使用initialize创建实例时的方式相同。

在此示例中,扩展时设置的变量是"丢失":

module Mod
  def self.extended(base)
    @from_module = "Hello from Mod"
    puts "Setting variable to: #{@from_module}"
  end

  def hello_from_module
    return @from_module
  end
end

class Klass
  def initialize
    @from_class = "Hello from Klass"
  end

  def hello_from_class
    return @from_class
  end
end

klass = Klass.new       #=> #<Klass:0x00000000ed8618 @from_class="Hello from Klass">
klass.extend(Mod)       #=> #<Klass:0x00000000ed8618 @from_class="Hello from Klass">
"Setting variable to: Hello from Mod"

klass.hello_from_class  #=> "Hello from Klass"
klass.hello_from_module #=> nil (warning: instance variable @from_module not initialized)

1 个答案:

答案 0 :(得分:2)

有很多方法可以做你所描述的。

最常见的一种方法是使用instance_variable_getinstance_variable_set

module ModA
  def self.extended(base)
    base.instance_variable_set(:@from_module, "Hello from Mod A")
    puts "Setting variable to: #{base.instance_variable_get(:@from_module)}"
  end

  def hello_from_module
    return @from_module
  end
end

另一种常见技术是使用evalexec方法中的任何一种。在这种情况下instance_exec

module ModB
  def self.extended(base)
    base.instance_exec { @from_module = "Hello from Mod B" }
    puts "Setting variable to: #{base.instance_exec { @from_module }}"
  end

  def hello_from_module
    return @from_module
  end
end