メソッドにブロックを渡すときの、{...}
とdo...end
の挙動の違いについてまとめてみた。
downtoメソッドの引数に数値のみ渡す
ブロックを渡さなければ括弧を明示していても、省略しても同じ。
pry(main)> 3.downto(0)
=> #<Enumerator: ...>
pry(main)> 3.downto 0
=> #<Enumerator: ...>
downtoメソッドの引数に数値とブロックを渡す
ブロックを渡すと括弧を明示しているか、省略しているかで結果が変わる。
以下④では、括弧を省略して{...}
でdowntoメソッドにブロックを渡そうとしているが文法エラーになっている。
{...}
の方がdo...end
より結合度が強い。
そのため④では0に対してブロックを渡すことになってしまい、エラーが出ている。
pry(main)> 3.downto(0) {|i| puts i}
3
2
1
0
=> 3
pry(main)> 3.downto(0) do |i| puts i end
3
2
1
0
=> 3
pry(main)> 3.downto 0 do |i| puts i end
3
2
1
0
=> 3
pry(main)> 3.downto 0 {|i| puts i}
SyntaxError: unexpected '{', expecting end-of-input
3.downto 0 {|i| puts i}
^
参考リンク
instance method Integer#downto(英語)
downto(limit) {|i| block } → self
downto(limit) → an_enumerator
Iterates the given block, passing decreasing values from int down to and including limit.
If no block is given, an Enumerator is returned instead.
5.downto(1) { |n| print n, ".. " }
print " Liftoff!\n"
# => "5.. 4.. 3.. 2.. 1.. Liftoff!"
instance method Integer#downto(日本語)
downto(min) {|n| ... } -> self
downto(min) -> Enumerator
self から min まで 1 ずつ減らしながらブロックを繰り返し実行します。 self < min であれば何もしません。
[PARAM] min:
数値
[RETURN]
self を返します。
[SEE_ALSO] Integer#upto, Numeric#step, Integer#times
ブロックをdo…endで書くか{…}で書くかにより挙動が変わる例
詳しくまとまっているので、挙動の違いの詳細についてはこちらを見た方がよいです
参考にしたツイート
以下のツイートにインスパイアされて記事を書きました。
参考: 武田哲也さんのRuby技術者認定試験受験記
#RubyGold 結合順のやつ。最後のだけ文法エラーになる。 3.downto(0) {|i| puts i} 3.downto(0) do |i| puts i end 3.downto 0 do |i| puts i end 3.downto 0 {|i| puts i}
— 武田哲也 (@__takeda) 2015, 1月 11