1. ホーム
  2. ruby-on-rails

[解決済み] Rubyのブロックにおけるdo.endと中括弧の比較

2022-04-23 05:28:49

質問

Rubyで複数行のブロックを定義するのに、do..endを使わず中括弧を使うべきだと、積極的に説得してくる同僚がいます。

私は、短いワンライナーには中括弧だけを使い、それ以外はすべてdo.endを使う派です。しかし、私はより大きなコミュニティに働きかけて、何らかの解決策を得ようと考えました。

では、どちらなのでしょうか、そしてその理由は?(あるべき姿のコードの例)

context do
  setup { do_some_setup() }
  should "do somthing" do
    # some more code...
  end
end

または

context {
  setup { do_some_setup() }
  should("do somthing") {
    # some more code...
  }
}

個人的には、上記を見ただけで疑問が解けましたが、より大きなコミュニティーにこれを公開したいと思います。

解決方法は?

複数行のブロックにはdo..endを、1行のブロックには中括弧を使うのが一般的ですが、この例で説明できるように、両者には違いもあります。

puts [1,2,3].map{ |k| k+1 }
2
3
4
=> nil
puts [1,2,3].map do |k| k+1; end
#<Enumerator:0x0000010a06d140>
=> nil

つまり、{}はdo..endよりも優先順位が高いので、何を使うか決める際にはその点に注意してください。

追伸:もう一つ、自分の好みを確立するために覚えておきたい例があります。

次のようなコードです。

task :rake => pre_rake_task do
  something
end

というのが本当の意味です。

task(:rake => pre_rake_task){ something }

そしてこのコード。

task :rake => pre_rake_task {
  something
}

というのが本当の意味です。

task :rake => (pre_rake_task { something })

ですから、実際に欲しい定義を中括弧で囲んで得るには、こうしなければなりません。

task(:rake => pre_rake_task) {
  something
}

パラメータに中括弧を使用することは、いずれにしてもやりたいことかもしれませんが、そうでない場合は、このような混乱を避けるために、これらのケースで do..end を使用することが最善でしょう。