ブロック

RubyではFor文は使うかわりにeachメソッドを使う。
Javaでいう拡張For文のようなもの。

s1 = ['a','b','c']
s2 = ""
s1.each do |s|
  s2 += s
end
puts s2 # abc

|s|のことをブロック変数という。配列から取り出した1要素が順に格納される。

do end を使わずに{ } で使って書くこともできる。
1行で書きたいときはこちらを使うらしい。

s1 = ['a','b','c']
s2=""
s1.each { |s| s2 += s }
puts s2# abc

ブロックを使うメソッド

# ブロックの戻り値を変数に入れられる
s1 = ['a','b','c']
s2 = s1.map { |s| s + '!' }
puts s2.to_s #["a!", "b!", "c!"]

# ブロックの戻り値が真になったものだけを入れる
s1 = ['a','b','c', 'b']
s2 = s1.select { |s| s == 'b' }
puts s2.to_s #=> ["b", "b"]

# selectメソッドの反対
s1 = ['a','b','c', 'b']
s2 = s1.reject { |s| s == 'b' }
puts s2.to_s #=> ["a", "c"]

# ブロックの戻り値が真になった最初の要素を返す
s1 = ['a','bbb','cccc', 'b']
s2 = s1.find { |s| s.size == 4 }
puts s2 #=> "cccc"

# sには最初だけinjectの引数が入る。
# 以降は前回のブロックの戻り値が入る。
# s2には各要素の値が入る。
s1 = ['a','b','c']
s2 = s1.inject('z') { |s, ss| s + ss }
puts s2 #=> "zabc"

&とシンボルを使ったもっと簡潔に書く方法
以下の条件を満たす時に使える。

  • ブロック変数が1つ
  • ブロック内で呼び出すメソッドに引数がない
  • ブロック内ではメソッドを1回呼び出すだけ

ブロック内でわざわざ変数を使う必要がないから省略する感じ?

s1 = ['a','b','c']
s2 = s1.map { |s| s.upcase }
puts s2.to_s #=>["A", "B", "C"]
#こう書き換えられる
s2 = s1.map(&:upcase)
puts s2.to_s #=>["A", "B", "C"]
参考文献

「プロを目指す人のためのRuby入門」