# Do..End v.s Braces

> 

Published: 2011-06-03
URL: https://kaochenlong.com/do-end-vs-braces

---

話說在 [Ruby](http://www.ruby-lang.org/en/) 裡，Block 可以用 `do..end` 的方式來寫，也可以用大括號來寫，例如用 do..end 的方式寫：

```ruby
(1..5).each do |i|
  puts i   # 得到1 2 3 4 5
end
```

用大括號的方式寫的話：

```ruby
(1..5).each { |i|
  puts i   # 一樣也是得到1 2 3 4 5
}
```

不過這兩天在看 [The Ruby Way](http://www.amazon.com/Ruby-Way-Second-Techniques-Programming/dp/0672328844) 的時候，看到一段是這樣寫的：

&gt; “Note that do and end may be substituted for the braces that delimit a block. There are differences, but they are fairly subtle.”
&gt; -- The Ruby Way(2nd edition), Page.22

書裡沒看到特別講到底哪邊不一樣，所以好奇的到處翻了網路上的一些資料，發現原來這兩種寫法的優先順序有一些些的不一樣，來看一段範例：

```ruby
my_array = [1, 2, 3, 4, 5]

p my_array.map { |item|
  item * 2  # 得到[2, 4, 6, 8, 10]
}

p my_array.map do |item|
  item * 2  # 得到[1, 2, 3, 4, 5]
end
```

為什麼結果跟預期的不一樣? 原來，因為省略了一些小括號，第二段的程式碼本來的意思是：

```ruby
p(my_array.map do |item| item * 2 end)  # 得到[2, 4, 6, 8, 10]
```

但卻因為 do..end 的優先順序比較小，原式被解析成：

```ruby
p(my_array.map) do |item| item * 2 end # 得到[1, 2, 3, 4, 5]
```

結果後面的 do..end 還沒開始跑，my_array.map 就先被 p 給印出來了..而用大括號的寫法的優先順序比較高，則不會有這個困擾。這樣那到底什麼時候要用 do..end? 什麼時候要用大括號? 還是乾脆全部都用大括號就好?

基本上如果 Block 的執行結果是會有回傳值的，那就建議用大括號來寫，其它的大致上都可以用 do..end 來寫。

**果然魔鬼都躲在細節裡!**

如果寫得有錯再請不吝指正，感謝！

