【一人 bugs.ruby Advent Calendar 2020】[Feature #17004] Provide a way for methods to omit their return value【22日目】
一人 bugs.ruby Advent Calendar 2020 22日目の記事になります。
[Feature #17004] Provide a way for methods to omit their return value
このチケットは任意のメソッドが戻り値を受け取るか受け取らないかを判定するメソッドの追加を追加するという内容のチケットです。
ということかというと RubyVM.return_value_is_used?
というメソッドを追加し、これをメソッド内で呼び出すと
- 戻り値を受け取る場合:
true
を返す - そうでない場合:
false
を返す
というような判定を行うことができます。
具体的に言うとこんな感じで判定する事ができます。
def hoge if RubyVM.return_value_is_used? pp "戻り値を受け取る" else pp "戻り値を受け取らない" end end hoge # "戻り値を受け取らない" value = hoge # "戻り値を受け取る" Array hoge # "戻り値を受け取る" hoge.nil? # "戻り値を受け取る" # 最後に呼び出したやつも? hoge # "戻り値を受け取る"
この判定メソッドを利用すると次のように『戻り値を受け取らない場合は無駄な処理を省く』事ができます。
class Hash def refresh(key) # 引数を受け取る場合のみ result を設定する if RubyVM.return_value_is_used? result = self[key] end self[key] = nil result end end homu = { name: "homu", age: 14 } homu.refresh(:name) p homu # => {:name=>nil, :age=>14} age = homu.refresh(:age) pp homu # => {:name=>nil, :age=>nil} pp age # => 14
class User < ActiveRecord::Base def update_name(name) update!(name: name) # reload した値を返す reload if RubyVM.return_value_is_used? end end
これは面白いアプローチですね。
ただし、次のように戻り値になる場合は『戻り値を受け取る』ことになるので注意。
def hoge if RubyVM.return_value_is_used? pp "戻り値を受け取る" else pp "戻り値を受け取らない" end end def foo hoge end foo # "戻り値を受け取る" def bar hoge nil end bar # "戻り値を受け取らない"
便利そうっちゃ便利そうだけどメソッドごとに RubyVM.return_value_is_used?
で処理を分岐するのはめっちゃきつそう…。
実際には極端に重くなるようなメソッドぐらいで使いそうな気がするけど…どうだろうか。