質問: Rubyインスタンス変数のキャッシュが保持される期間を知りたいです。 ``` class Hoge< ActiveRecord::Base def hoge @hoge =|| Hoge.all end end ``` 上記のような@hogeインスタンス変数がキャッシュされていて どのタイミングでキャッシュが無くなってHoge.allが呼ばれるようになるか知りたいです。 HogeクラスはActiveRecordになります。
回答: 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`がまた呼び出される、という可能性はあります。 そもそも個々のレコードを表すインスタンスがそれぞれ別個に全てのレコードを持つというのが変だと思うのですが。