rubyのyieldについて

yieldはrailsで見かけますが、よく理解していなかったです。

ここでyieldについて説明します。

ブロックについて

yieldについて話をする前に、ブロックの話をしないといけません。

そもそもブロックってなんですか?というところですね。

name_list = %w(alice bob tom)

name_list.each do |name|
  puts "my name is #{name.capitalize}"
end

ここのeachメソッドはブロックを受け取り、要素の数だけブロックを実行します。

yieldについて

yieldは受け取ったブロックを実行してくれます。

ブロック要素がないとエラーになってしまいます。

def block_sample
  puts 'test1'
  yield
  puts 'test2'
end

block_sample do
  puts "I'm a block man"
end

→
test1
I'm a block man
test2

これはblock_sampleからブロックを渡しています。

ブロックを渡さないとこうなります。

rb:3:in `block_sample': no block given (yield) (LocalJumpError)

ブロックを受け取った時にだけ実行するにはblock_given?を使います。

def block_sample
  puts 'test1'
  yield  if block_given?
  puts 'test2'
end

ブロックを配列で渡してあげましょう

def block_sample
  puts 'test1'
  yield  if block_given?
  puts 'test2'
end

name_list = %w(alice bob tom)

block_sample do
  name_list.each do |name|
    puts "my name is #{name.capitalize}"
  end
end

→
test1
my name is Alice
my name is Bob
my name is Tom
test2

これを下記のように変更してみました。

def block_sample
  puts 'test1'
  puts yield
  puts 'test2'
end

name_list = %w(alice bob tom)

block_sample do
  name_list.each do |name|
    "my name is #{name.capitalize}"
  end
end

→
test1
alice
bob
tom
test2

ブロックは|name|だけなんですね。

この違いはputsによって、ブロックの範囲が変更されたんですね。

奥が深いな・・・

まとめ

ブロックという概念を知っておきましょう。