blogyuji.developerによる落書き。プログラミングやカメラをメインにだらだらと書いてます。apps2018年9月3日月曜日Rubyでメモ化するときの話あるクラスに以下のような自身が持つemailでAccountを検索して返すメソッドがあるとしましょう。self.email)endこのメソッドには問題があります。呼び出しのたびに検索処理が行われてしまうことです。解決するためにはどうするでしょうか。解決方法はいくつかありますが、ここでは以下のようにメモ化するという選択をしたとしましょう。self.email)endこれで初回の呼び出しのみで検索が行われ、2回目以降はインスタンス変数に設定された値が使われるようになります。よし、完璧だ、と思ったでしょうか。これでもまだ問題があります。検索処理がnilを返す可能性です。検索処理でnilが返らない前提ならば、以下のように例外が発生するfind_by!のようなメソッドを使用しておけばヒットしないケースは例外的ケースのみということで問題にはならないでしょう。self.email)endここでは検索処理でnilが返ることがある前提で話を進めましょう。nilが返った場合に何が問題か。検索処理でnilが返る場合、accountメソッドが呼ばれるたびに検索処理を行ってしまうのです。それもそのはず、Rubyの||=演算子は左辺が偽の場合に右辺の処理行い左辺に代入する演算子だからです。Rubyで偽の場合というのはnilかfalseの場合です。Rubyのインスタンス変数は未初期化であればnilとして扱われます。初回の実行時はこれにより右辺が評価され、インスタンス変数に値が設定されます。右辺が偽を返さない場合は2度目以降は左辺の評価が真となりますので右辺が評価されることなく終わりますが、右辺が偽の値を返していた場合は2度目以降でも左辺の評価が偽となり右辺の評価が行われてしまいます。これは望んでいる挙動ではないことでしょう。いう場合は以下のようにinstance_variable_defined?を使用します。self.email)endこれならばインスタンス変数が未定義の場合(つまり初回呼び出しの場合です)は、検索処理が行われその結果が何であろうともインスタンス変数に代入されます。2度目以降の呼び出しでは設定された値がnilであってもその値が返されます。検索処理は1度しか行われません。これで望んでいた動作になりました。