0
module MyModule
    def self.my_method
        @instance_variable ||= "some string"
    end
end

考虑另一个OtherModule包含MyModule. 当多次OtherModule调用中的代码my_method@instance_variable被多次实例化?还是只有一次?

4

1 回答 1

1

更新答案:

  1. 如果委托模块调用该方法,您将收到错误消息。
  2. 如果原始模块调用该方法,则类实例变量仅实例化 1 次。
  3. 如果你想在一个模块中定义“类方法”,你不能定义self.xx然后简单地扩展/包含它。您应该“扩展”它,或“将其包含到本征类中”,例如

    module SomeModule
      def self.aim_to_be_class_method ;    end;  
      def aim_to_be_instance_method ;    end;
    end
    
    # class methods:  []
    # instance methods: ["aim_to_be_instance_method"]
    class SomeClassIncludingTheModule
      include SomeModule  
    end
    
    # class methods:  ["aim_to_be_instance_method"]
    # instance methods: []
    class SomeClassExtendingTheModule
      extend SomeModule   
    end
    
    # class methods:  ["aim_to_be_instance_method"]
    # instance methods: []
    class SomeClassMadeEigenClassIncludingModule
      class << self
        include SomeModule
      end
    end
    

您的代码是“类实例变量”的示例。根据书<< metaprogramming ruby​​>>,第127页,您可以将“类实例变量”视为Java的静态字段。所以,我认为大多数情况下,它应该运行一次。

有关更多详细信息,请编写单元测试,看看会发生什么?不久后,我将使用我自己编写的单元测试代码更新我的答案。

更新:我的单元测试和结果:

# all of the code is placed in a file: class_instance_variable_test.rb

# define a class so that we see its initialize process
class Apple
  def initialize
    puts "Apple initialized~"
  end 
end

# define an original_module that calls Apple.new
module OriginalModule
  def self.original_method
    @var ||= Apple.new
  end 
end

# define another module to call the original_module
module DelegateModule
  include OriginalModule
end

# now the test begins
require 'test/unit'
class ClassInstanceTest < Test::Unit::TestCase

  # output of this test case: 
  # NoMethodError: undefined method `original_method' for DelegateModule:Module      
  def test_if_delegate_module_could_call_original_method_by_including_original_module
    DelegateModule.original_method
  end

  # output of this test case: 
  # ----- calling from original_method, 3 times called, how many times initialized?
  # Apple initialized~
  # ------ ends
  def test_if_we_could_call_original_method_from_original_module
    puts "----- calling from original_method, 3 times called, how many times initialized? "
    OriginalModule.original_method
    OriginalModule.original_method
    OriginalModule.original_method
    puts "------ ends "
  end

end
于 2012-04-04T22:56:59.340 回答