4

次のような の Ruby イディオムを偶然発見し||=()ました。

def app_logger
  @app_logger ||= (
    logfile = File.open(::Rails.root.join(LOG_FILE), 'a')
    logfile.sync = true
    AppLogger.new(logfile)
  )
end

{}の代わりに使用しようとしまし()たが、うまくいきませんでした。{}ブロックを囲むためのものだと思いました。

これは既知のイディオムですか?スタイルいいですか?

この種の括弧の使用に関するドキュメントはあまり見つかりませんでした。どんなポインタも役に立ちます。

()この投稿は、 の使用ではなく、この方法の使用に関するものであることに注意してください||=。この後者の慣用句については、すでに多くの投稿があります。

4

3 に答える 3

6

Ruby で実行できる多くのことと同様に、それらの多くは実行すべきではなく、これもその 1 つです。

他の機能が既にある場合にコードをグループ化するためにブラケットを使用すると、混乱を招く可能性があり、多くのコーディング スタイル ガイドに反することはほぼ確実です。私が管理しているコードでこれを見つけたら、すぐに修正します。

最善の方法は、begin/endマーカーを使用して、何が起こっているのかを完全に明確にすることです。

def app_logger
  @app_logger ||= begin
    logfile = File.open(::Rails.root.join(LOG_FILE), 'a')
    logfile.sync = true
    AppLogger.new(logfile)
  end
end

Ruby では多くのものが 1 つの値に評価されますが、 の内容(...)は明らかにそれらの 1 つです。

foo ||= (a=10; a+10)「より良い」というあなたの他の例も、かなり物議を醸しています。これは 2 つの代入と加算を行いますが、条件付きでのみです。これはほとんどの場合、結果を明確にするためにbegin/を付けて長い形式で記述した方がよいでしょう。enda+10

スタイルの観点から、その「重要な」部分a+10、行末の , を隠すことは悪いことであり、見落とされる可能性があります。それを最後の行にすることで、非常に明確になります。これはif、長い行の最後にステートメントを追加するのも良くない理由でもあり、行が条件付きでのみ実行されることを隠します。

簡潔さへの懸念は、読みやすさへの懸念によって常に打ち負かされます。ディスクに数バイトを保存しても、誰かがコードを読み違えたために重大なバグが発生した場合、少しも役に立ちません。

あなたが自分の賢さに巻き込まれたとき、誰かが将来あなたになることができるということ。ある時点で、それは私たち全員に起こりました。

于 2013-05-01T15:07:16.163 に答える
2

@tadman の回答に加えて、より Ruby に似た方法でメソッドを記述すると、読みやすさが維持され、適切でタイトに保たれることに反論します。

def app_logger
  return @app_logger if @app_logger

  logfile = File.open(::Rails.root.join(LOG_FILE), 'a')
  logfile.sync = true
  @app_logger = AppLogger.new(logfile)
end

このように書いた私の意図と理論的根拠については、@ fotanus のコメントに対するこの回答への私のコメントを参照してください。

私たちの脳は、プログラミングを学び、新しい言語を学ぶにつれて、パターンを見るように条件付けられます。パターンがデバッガーまたは C、Perl、Python、Java、または Ruby によって出力された 16 進コードであるかどうかに関係なく、パターンは引き続き表示されます。それらを目にすることに慣れると、コードを変更して、見慣れた構造に似せたいと思う傾向があります。そのため、Perl や C のプログラマーは、最初は C や Perl のように Java、Python、Ruby を書く傾向があります。「美しさは見る人の目の中にある」とはいえ、その同じ美しさは、整然とした庭園やフェアウェイの真ん中で野生の花が場違いであるのと同じように、場違いなときは雑草です。プログラミング言語の言語で書くべきです。それは、その土地に住む人々が期待する話し方だからです。

覚えておくべきことは、私たちは個人的には、コードを複数行から 1 文字に減らすことができるコード研究の怪物かもしれないということです。同じ口径でなければなりません。コードのクランチングは、特にそのコードが本番環境で実行されていて、ジュニアプログラマーによって維持されており、拡張またはデバッグする必要がある場合は特に、最小サイズに縮小されるかなり前に、収穫逓減のポイントに常に到達します。時計が時を刻んでいる。Minutes = dollars私が働いている場所では、ドルには非常に大きな乗数があり、バグ爆弾が爆発すると、壁からゴキブリのような管理者が漏れます。(ああ...私はマネージャーをゴキブリと呼びましたか?なんでも。)

イベントの翌朝に呼び出され、デバッグ/修正または修正/拡張を容易にするコードを作成したことに対して感謝されることは、午前 2 時 45 分に呼び出されてオンラインで助けを求められるよりもはるかに優れています。私は自分の睡眠とコーディング パートナーの睡眠を大切にしており、保守可能なコードを最優先事項として推進しています。

それが私の 0.02 ドルです。

于 2013-05-01T15:45:44.593 に答える
0

私の意見では、括弧は本当に醜いです。ロガーの作成の背後にあるロジックをメソッドに委譲しないのはなぜですか?

def app_logger
  @app_logger ||= instantiate_app_logger
end

def instantiate_app_logger
  logfile = File.open(::Rails.root.join(LOG_FILE), 'a')
  logfile.sync = true
  AppLogger.new(logfile)
end

しかし、それがいくつかの OOP やコードを壊してしまうのではないかと心配しています。渡されたパスに基づいて AppLoger クラスがファイルを開けず、同期をオンにできないのはなぜですか? とてもきれいになります。

于 2013-05-01T19:39:47.927 に答える