Hatena::Grouprubyist

trotrの日記

2007-07-18

do-endと{ }の違い 05:17

rubyブロックを使うときに

  • do-endを使う方法
  • { } を使う方法

はほとんど同じような動作をしますが、解釈のされかたが少し違います。

通常

引数の0のかっこを省略しなければ、どちらも意図したとおりの動作を返します。

(1..3).inject(0) do sum, n| 
	sum + n 
end
  #もしくは  (1..3).inject(0) {|sum, n| sum + n} 
=>6

括弧がないとき

do-endの場合は
(1..3).inject 0 do |sum, n| sum + n end
=> 6
	
  # [1,2,3].( inject 0 { sum+n })  こんな感じに解釈されている
   ##==ここでの表記のしかた==
   ## (<レシーバ>.<メソッド> <引数>)
       ## (<レシーバ>.<メソッド> <引数> { <ブロックの中身> } ) ※ブロックがある場合
一方「{ }」を使った場合
(1..3).inject 0 {|sum, n| sum + n} 
=> SyntaxError: compile error

 # [1,2,3] .(inject ( 0 { sum+n } ) ) do-endとはちょっと解釈のされ方が違っている。
						 (0にブロックが渡されてしまっている。)

id:bongoleさんの事例*1

p [1,2,3].collect do |i| i  end.compact
=>nil
NameError: undefined method `compact' for nil:NilClass (NoMethodError)
  # (p ([1,2,3].collect ({ i }.compact) ) ) こんな感じかな?

p [1,2,3].collect { |i| i  }.compact 
=> [1, 2, 3]
  # (p (compact ([1,2,3].collect { i })) ) 

というわけで、compactメソッドが適応される対象が

となるので、上記のような違いが起きるんだと思います。

間違ってたらすみません><

*1:一行に収めるために、少し形を変えてあります。

trotrtrotr2008/04/19 18:39まちがっているかも><