🎃
RubyエンジニアがJavaScriptを書くときに知っておくべきreturnの罠
はじめに
RubyからJavaScript(以下JS)に入門するとき、「なぜかfilterやsomeが思ったとおりに動かない」と感じることがあります。
その原因の一つが JavaScriptではreturnを明示的に書かないと値が返らない という仕様です。
この記事では、Rubyエンジニアがつまずきやすいこの点にフォーカスし、JSとの違いと注意点を紹介します。
Rubyでは「最後に評価された値」が返る
Rubyでは、ブロックの最後に評価された値がそのまま戻り値になります。
[1, 2, 3].select do |n|
n > 1
end
# => [2, 3]
このコードでは、ブロックの最後にn > 1という式があるので、その評価結果(true or false)が自動的に返されます。
JavaScriptでは return がないと返らない
JavaScriptでは、関数の戻り値は明示的にreturnしないと返されません。
[1, 2, 3].filter((n) => {
n > 1; // returnしていないので undefined を返す
});
// => []
このコードは一見Rubyと同じように見えますが、実はブロック内で値を返していないため、filterはすべての要素を弾いてしまいます。
正しい書き方
明示的にreturnを使う:
[1, 2, 3].filter((n) => {
return n > 1;
});
// => [2, 3]
あるいは、アロー関数の省略記法を使う:
[1, 2, 3].filter(n => n > 1);
// => [2, 3]
アロー関数でブロック({})を使わなければ、returnは省略可能です。
よくあるパターン:someやfindでも同様
some, find, map, reduceなど、戻り値が重要なメソッドでも同じ注意が必要です。
[1, 2, 3].some((n) => {
n > 2;
});
// => false(常に undefined を返すため)
// 正しくは
[1, 2, 3].some((n) => {
return n > 2;
});
// => true
まとめ
項目 | Ruby | JavaScript |
---|---|---|
戻り値 | ブロックの最後の式 | 明示的にreturnが必要(※省略記法を除く) |
filter, some, など | 式を書くだけでOK | returnしないと常にfalse扱いになる |
おわりに
RubyとJavaScriptの間には細かな文法の違いが多数ありますが、returnの扱いは特に罠になりやすいポイントです。
JSに慣れていないRubyエンジニアは「とりあえずreturn書く」というクセをつけるところからスタートすると、安全に開発を進められるでしょう。
Discussion
proposal: do expressions がほしくなる話ですかね?