web-dev-qa-db-ja.com

Rubyで明示的に返すのは良いスタイルですか?

Pythonバックグラウンドから来て、スタイルに関しては常に「正しい方法」(「Pythonの」方法)がありますが、Rubyにも同じことが存在するのでしょうか。 。私は独自のスタイルガイドラインを使用してきましたが、ソースコードをリリースすることを考えており、存在する可能性のある未記述のルールを遵守したいと考えています。

メソッドでreturnを明示的に入力するのは "Ruby Way"ですか?あり、なしで行われましたが、正しい方法はありますか?おそらくtimeを行う権利がありますか?例えば:

def some_func(arg1, arg2, etc)
  # Do some stuff...
  return value # <-- Is the 'return' needed here?
end
147
Sasha Chedygov

古い(および「回答済み」)質問ですが、回答として2セントで投げます。

TL; DR-する必要はありませんが、場合によってはコードをより明確にすることができます。

明示的な戻り値を使用しないことは「Rubyの方法」かもしれませんが、見慣れないコードで作業するプログラマーや、Rubyのこの機能になじみのないプログラマーにとっては混乱を招きます。

これはやや不自然な例ですが、イメージングにはこのような小さな機能があり、渡された数値に1を加算して、インスタンス変数に割り当てます。

def plus_one_to_y(x)
    @y = x + 1
end

これは、値を返す関数であるかどうかを意味していましたか?開発者が何を意味したかを言うのは非常に困難です。どちらもインスタンス変数を割り当て、さらに割り当てられた値を返すからです。

後で、別のプログラマー(おそらく、実行されたコードの最後の行に基づいてRubyが戻る方法に慣れていない)がやって来て、ロギング用の印刷ステートメントを入れたいと考え、関数がこの...

def plus_one_to_y(x)
    @y = x + 1
    puts "In plus_one_to_y"
end

これで、関数は壊れています何かが戻り値を期待している場合。戻り値が期待されていない場合は問題ありません。明らかにコードチェーンのさらに下のどこかで、これを呼び出すものが戻り値を期待している場合、期待したものを取り戻せないので失敗します。

本当の質問はこれです:戻り値を本当に期待するものはありましたか?これは何かを壊したかどうか?将来、何かを壊すでしょうか?知るか!すべての呼び出しの完全なコードレビューのみが通知されます。

したがって、少なくとも私にとって、ベストプラクティスのアプローチは、重要な場合は何かを返すことを非常に明確にするか、そうでない場合は何も返さないことです。

したがって、小さなデモ関数の場合、値を返すことを望んでいると仮定すると、このように記述されます...

def plus_one_to_y(x)
    @y = x + 1
    puts "In plus_one_to_y"
    return @y
end

そして、プログラマーにとって値を返すことは非常に明確であり、彼らが気付かないうちにそれを破ることははるかに困難です。

または、このように記述してreturnステートメントを省略できます...

def plus_one_to_y(x)
    @y = x + 1
    puts "In plus_one_to_y"
    @y
end

しかし、どうしてわざわざWordのリターンを除外するのでしょうか?そこに入れて、何が起きているのかを100%明確にしてみませんか?文字通り、実行するコードの能力に影響はありません。

216
Tim Holt

いいえ。良いRubyスタイルは、通常、アーリーリターンに対して明示的なリターンのみを使用します。 Rubyは、コードのミニマリズム/暗黙の魔法で大きな役割を果たします。

とはいえ、明示的なリターンが物事をより明確にしたり、読みやすくしたりしても、何も害はありません。

66
Ben Hughes

私は個人的にreturnキーワードを使用して、機能メソッド、つまり主に戻り値に対して実行されるメソッドと手順メソッドを区別しています。主に副作用のために実行されます。そのため、戻り値が重要なメソッドでは、余分なreturnキーワードを取得して、戻り値に注意を引きます。

callingメソッドの場合、同じ区別を使用します。関数型メソッドは括弧を取得しますが、手続き型メソッドは取得しません。

最後に重要なことですが、ブロックとの区別も使用します。機能ブロックは中括弧を取得し、手続き型ブロック(つまり、「何か」を行うブロック)はdo/endを取得します。

しかし、私はそれについて宗教にならないようにしています:ブロックでは、中括弧とdo/endは異なる優先順位を持ち、明示的な括弧を追加して式を明確にするのではなく、他のスタイル。メソッドの呼び出しについても同じことが言えます。パラメーターリストの周りにかっこを追加すると、コードが読みやすくなる場合は、問題のメソッドが手続き型であっても実行します。

31
Jörg W Mittag

実際に重要なことは、以下を区別することです。

  1. 関数-戻り値に対して実行されるメソッド
  2. 手順-副作用のために実行されるメソッド

Rubyにはこれらを区別するネイティブな方法がありません。これにより、プロシージャside_effect()と、プロシージャの暗黙的な戻り値を悪用することを決定する別の開発者(基本的に不純な関数として扱う)を書くことに脆弱になります。

これを解決するには、ScalaとHaskellの本から葉を取り、proceduresが明示的にnil(別名Unitまたは他の言語の())。

これに従う場合、明示的なreturn構文を使用するかどうかは、個人的なスタイルの問題になります。

関数とプロシージャをさらに区別するには:

  1. 機能ブロックを中括弧で、手続き型ブロックをdo/endで書くというJörgW Mittagの素晴らしいアイデアをコピーします。
  2. プロシージャを呼び出すときは()を使用しますが、関数を呼び出すときは

JörgW Mittagは実際には別の方法を推奨していることに注意してください-プロシージャの()sを避けます-しかし、特にアリティが0の場合、副作用のあるメソッド呼び出しを変数と明確に区​​別したいのでお勧めできません。 詳細については、メソッド呼び出し のスカラスタイルガイド。

13
Alex Dean

スタイルガイド では、最後のステートメントでreturnを使用しないでください。引き続き使用できます 最後のものでない場合 。これは、コミュニティが厳密に従う規則の1つであり、Rubyを使用している人とのコラボレーションを計画している場合は、そうする必要があります。


そうは言っても、明示的なreturnsを使用する主な論点は、他の言語から来た人にとって混乱を招くということです。

  • 第一に、これはRubyに完全に限定されているわけではありません。たとえば、Perlには暗黙的な戻り値もあります。
  • 第二に、これが当てはまる人々の大半はALGOL言語から来ています。それらのほとんどは、Rubyよりも方法 "low level"であるため、何かを成し遂げるには、より多くのコードを書く必要があります。

Java)のメソッドの長さ(ゲッター/セッターを除く)の一般的なヒューリスティックは、1画面です。その場合、メソッド定義が表示されていないか、どこから戻るかをすでに忘れている可能性があります。

一方、Rubyメソッドに固執するのが最善です 10行未満 。それを考えると、なぜ彼は〜10%を書かなければならないのか疑問に思うでしょうそれらが明確に暗示されている場合、より多くのステートメント。


Rubyにはvoidメソッドがなく、すべてがはるかに簡潔なので、どれにもオーバーヘッドが追加されません明示的なreturnsを使用した場合の利点。

7
ndnenkov

質問はPythonがそれを行う決定的な方法に言及し、Rubyが同様の標準を持っているかどうかを尋ねるので、Ben Hughesに同意し、Tim Holtに同意しません。

それは。

これはこの言語のよく知られた機能であり、Rubyの問題をデバッグすることを期待される人は誰でも、それについて知ることが合理的に期待されるはずです。

4
Devon Parsons

ほとんどの場合、どのスタイルを好むかは問題です。メソッドの途中から戻る場合は、returnキーワードを使用する必要があります。

1
Praveen Angyan

ベンが言ったように。 「Rubyメソッドの戻り値は関数本体の最後のステートメントの戻り値である」という事実により、returnキーワードはほとんどのRubyメソッド。

def some_func_which_returns_a_list( x, y, z)
  return nil if failed_some_early_check


  # function code 

  @list     # returns the list
end
0
Gishu