2012-02-29 (Wed)
_ returnすべきか、せざるべきか
Rubyについてよくある議論で、returnを書くべきか、省略すべき(途中でreturnするケースは除く)か、というのがある。 いつだったかのRubyConfでコードの書き方についてのパネルみたいなのがあって、会場からTwitterで質問できたので聞いてみたら、会場のほとんどの人がreturnを書かない派で、returnを書く派のパネリストがJava guy!と罵られていた。もっと英語ができたら援護してあげられたのだけど。
僕がreturnを書くのは、
def foo bar baz end
みたいなコードがあった時に、bazが値を返すことを期待しているのか、たんに副作用のために呼んでいるのかを区別しにくいからだ。 単純なgetterなんかではreturnを省略しても問題ないと思うけど。
return書かない派の話を聞くと、例えば関数型言語ではreturnがない(Haskellにはreturnがあるけど全然別物)じゃないか、といった意見が出ることがあるが、関数は値を返すに決まっているからそもそも上記のような問題はない。でもRubyは命令型言語なのだ。
Rubyでも関数型っぽいコードでreturnを省略するのは違和感がない。例えばこんなコード。
def sum_of_squares(ary) ary.map { |i| i ** 2 }.inject(&:+) end
でも次のコードはちょっと不恰好に見える。
def sum_of_squares(ary) result = 0 for i in ary result += i ** 2 end result end
injectを使う時も似たようなことがあって、上のsum_of_squaresのinjectはすっきりしているけど、
def to_hash(ary) ary.inject({}) do |h, (k, v)| h[k] = v h end end
みたいなコードはむしろ格好わるい。
副作用を使うなら割り切って
def to_hash(ary) ary.each_with_object({}) do |(k, v), h| h[k] = v end end
とした方が潔い。
結局、結論としては「読みやすければいいんじゃないの?」というところで、何か面白くなくなってしまったな。
_ knu [個人的には、Rubyでは値を持たない式がないのですべての(public)メソッドはその返り値に気を配るべきで、内部で..]
_ なかむら(う) [「でも次のコードはちょっと不恰好に見える。」の例は、最後が return result だったとしたらどうか、と..]
_ shugo [knuさん: 値を返さない人だけreturnを書くというのは斬新ですけど、普通の言語と逆ですよねえ。 なかむら(う..]
_ knu [や、nilの方が推奨ですよw 空のreturnはあんまり好みじゃないです。 たまたま今perlの仕事をしててそうい..]
_ knu [あ、言いたかったのは(perlではreturn;とundef;は意味が違う)でした。 perlでリストを返す関数の場..]
_ shugo [なるほど、Perlも難しいですね。]