更新答案:
- 如果委託模塊調用該方法,你會得到一個錯誤。
- 如果原始模塊調用該方法,則該類實例變量僅實例化了1次。
如果你想在模塊中定義「類方法」,你不能定義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