2009-03-30 15 views
72

は、私は私がインスタンス変数を使用したいいくつかのモジュールを持っている私は現在、このようにそれらを初期化しています:。Rubyでモジュールのインスタンス変数を初期化するにはどうしたらいいですか?

module MyModule 
    def self.method_a(param) 
    @var ||= 0 
    # other logic goes here 
    end 
end 

また、私はそれらを初期化するためにinitメソッドを呼び出すことができます。

def init 
    @var = 0 
end 

しかし、これは私が常にそれを呼び出すことを覚えなければならないことを意味するでしょう。

これを行うには良い方法がありますか?

def init(var=0) 
@var = var 
end 

をそして、あなたは何を通過しない場合には0にデフォルト設定されます:

+3

最初のコードブロックは、モジュールインスタンスvar(MyModuleの型オブジェクトのスコープ内のvar)を設定せず、2番目のコードブロックは "plain"インスタンスvar(varを含むインスタンスの範囲内のvarモジュール)?私はこれらの2つのコードブロックが同じことをしないと思います... –

答えて

98

は、モジュール定義でそれらを初期化します。

module MyModule 
    # self here is MyModule 
    @species = "frog" 
    @color = "red polka-dotted" 
    @log = [] 

    def self.log(msg) 
    # self here is still MyModule, so the instance variables are still available 
    @log << msg 
    end 
    def self.show_log 
    puts @log.map { |m| "A #@color #@species says #{m.inspect}" } 
    end 
end 

MyModule.log "I like cheese." 
MyModule.log "There's no mop!" 
MyModule.show_log #=> A red polka-dotted frog says "I like cheese." 
        # A red polka-dotted frog says "There's no mop!" 

これは、モジュールが定義されているときにインスタンス変数を設定します。

# continued from above... 
module MyModule 
    @verb = "shouts" 
    def self.show_log 
    puts @log.map { |m| "A #@color #@species #@verb #{m.inspect}" } 
    end 
end 
MyModule.log "What's going on?" 
MyModule.show_log #=> A red polka-dotted frog shouts "I like cheese." 
        # A red polka-dotted frog shouts "There's no mop!" 
        # A red polka-dotted frog shouts "What's going on?" 
+17

誰かが鋭いガイドを読んでいます;) –

+12

これはしばらくしていますが、そうです:)。加えて、私はMessrs FooとBarについて言われている必要があると言われています。 – rampion

+0

ありがとうございます。 – Geo

6

あなたは使用することができます。初期化はいつでもあなたを呼ばれているので、私は次のことを言うだろう、クラスの

module AppConfiguration 
    mattr_accessor :google_api_key 
    self.google_api_key = "123456789" 
... 

end 
+0

モジュールで何かをする前にこの関数を呼び出す必要がありますか? – Geo

+0

私はその問題を避けるために第2の方法を追加しました - それはレールコードからです – Brian

2

:あなたは毎回それを呼び出すためにしたくない場合は

は、あなたはこのようなものを使用することができます。新しいクラスのインスタンス。 Practical Rubyから

def initialize 
    @var = 0 
end 

それは、クラスのinitialize含む が スーパーを呼び出す場合、モジュールの 初期化が呼び出されると言うことになりますが、この が結果であることを言及していませんどのようにスーパー作品 どこでも、 のための特別な処理を初期化。 (なぜ1が 初期化は、特別な処理を取得すると仮定かもしれない? それが視界に に関して特別な処理を取得しているため。特別な場合 混乱を作成します。)

+1

それはモジュールなので、呼び出されるように初期化されますか?それが私の最初の答えです。私はそれが呼び出されていないことを説明するために2番目を追加しました。 – Brian

+1

OPは具体的に言及したモジュールであり、クラスではありません – Zensaburou

1

私は、あなたがこの

をやっ クラスのインスタンス変数を設定することができます同様のquestionに答え:あなたはalwasys後で、 をより多くのインスタンス変数やメソッドの定義を追加したり、既存のものを再定義するモジュールを再度開くことができ、覚えておいてください
module MyModule 
    class << self; attr_accessor :var; end 
end 

MyModule.var 
=> nil 

MyModule.var = 'this is saved at @var' 
=> "this is saved at @var" 

MyModule.var  
=> "this is saved at @var" 
2

明らかに、Rubyのモジュールでインスタンス変数を初期化するのは悪いフォームです。 (理由から、私は完全には理解していないが、物事がインスタンス化される順序に関係する。)

ベストプラクティスがそうのように、怠惰な初期化でアクセサを使用しているようだ:

module MyModule 
    def var 
    @var ||= 0 
    end 
end 

その後@varのゲッターとしてvarを使用してください。

+3

これは決してあなたが 'nil'または' false'に@varを設定することを許さないことに注意してください – steel

関連する問題