24185


Rubyインスタンス変数のキャッシュが保持される期間を知りたいです。

[code]

    class Hoge< ActiveRecord::Base
      def hoge
        @hoge =|| Hoge.all
      end
    end
    
[/code]

上記のような@hogeインスタンス変数がキャッシュされていて  
どのタイミングでキャッシュが無くなってHoge.allが呼ばれるようになるか知りたいです。  
HogeクラスはActiveRecordになります。


CC BY-SA 3.0
2016-04-20T10:14:36.703
24184
2016-04-21T02:12:42.893
2016-04-21T00:59:26.593
10851
10851
question
ruby-on-rails ruby rails-activerecord
Rubyインスタンス変数のキャッシュ保持期間について


Rubyにはインスタンス変数を自動的にキャッシュするような機能はありません。インスタンスが生成されると同時にインスタンス変数も初期化され、インスタンスが破棄されるときにインスタンス変数の内容も破棄されます。キャッシュはされないので、キャッシュの保持期間もありません。

あなたのコード例で言うと、`Hoge`クラスのインスタンス生成直後に`hoge`メソッドを呼べば、必ず`Hoge.all`が呼ばれます。その後、同一のインスタンスに対して`hoge`メソッドを呼んでも(その途中で明示的に`@hoge`の内容をクリアしない限り)`Hoge.all`は呼ばれません。

RailsのActionクラスの場合、インスタンスはリクエスト処理ごとに生成されます。(同じActionクラスで処理されるリクエストが同時に届いた場合、同一Actionクラスのインスタンスが複数生成されます。)  
従って、一つのリクエストの中で最初に(`@hoge`に値が設定される前に)`hoge`を呼んだ場合、`Hoge.all`が呼ばれますが、その後同じリクエスト処理の中で`hoge`を呼んでも`Hoge.all`は実行されません。

ActiveRecordのようなModelクラスの場合、同時に複数のインスタンスが生成されることが多いので話はもうちょっと複雑になりますが、「インスタンス変数は個々のインスタンスがそれぞれ別々に保持している」ことが分かっていれば結局同じことです。

* * *

_HogeクラスはActiveRecordになります。_  
わざわざ追記していただきましたが、上記の通りです。ActiveRecordではクエリー結果やデータベースとの接続に関する状態をキャッシュしていますが、特定のユーザ定義のインスタンス変数の中身をキャッシュすることはありません。  
インスタンス変数ではなく、`Hoge.all`メソッドが何度か呼ばれたときに、2度目からはキャッシュの内容を返す可能性はありますが、これは「インスタンスの集合体」であって、特定のインスタンス変数ではありません。

つまり「`Hoge`クラスはActiveRecord」であっても、「`Hoge`クラスのインスタンス生成直後に`hoge`メソッドを呼べば、必ず`Hoge.all`が呼ばれます。その後、同一のインスタンスに対して`hoge`メソッドを呼んでも`Hoge.all`は呼ばれません。」と言う事情は変わりません。ただ、「インスタンス生成直後」かどうかを一般的に判定はできないので、それに依存したコードを書くべきではないでしょう。

当然ながらインスタンス変数は各インスタンスごとに別個のものですから、`Hoge`クラスのあるインスタンスについては`Hoge.all`が呼ばれて`@hoge`に値が保持されていたとしても、別のインスタンスの`@hoge`は空っぽで、そちらのインスタンスの`hoge`メソッドを呼ぶと`Hoge.all`がまた呼び出される、という可能性はあります。  
そもそも個々のレコードを表すインスタンスがそれぞれ別個に全てのレコードを持つというのが変だと思うのですが。


CC BY-SA 3.0
2016-04-20T11:16:32.123
24185
2016-04-21T02:12:42.893
2016-04-21T02:12:42.893
13972
13972
24184
answer