rails lib目录中的模块

时间:2012-04-04 21:31:45

标签: ruby-on-rails module instantiation instance-variables

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

考虑另一个包含OtherModule的模块MyModule。当OtherModule多次调用my_method的代码@instance_variable多次实例化时?或者只是一次?

1 个答案:

答案 0 :(得分: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
    
  4. 您的代码是“类实例变量”的示例。根据该书&lt;&lt;元编程ruby&gt;&gt;,第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