:pぴー.sendせんど(:pぴー, :pぴー)

mokoaki
mokoriso@gmail.com

2017/07/22

ブロック

Ruby技術者認定試験の書籍写経メモ

def moko(a)
  a + yield
end

moko(1) do
  2 + 3
end
=> 6

moko(1) { 2 * 3 }
=> 7
# スコープを作る、とは?
# その正体は?クロージャ?
hage1 = 1

def moko
  yield
end

moko do
  hage1 = 100
  hage2 = 100
end

hage1
=> 100
hage2
NameError: undefined local variable or method 'hage2'

ここ、重要そうな事が書いてあるぞ!

ブロックは引数を受け取れる

def moko(num)
  yield(num, 2)
end

moko(1) do |a, b|
  a + b
end
=> 3

メソッド内でブロックが指定されたかどうか判定

def moko(num)
  return 'block...' if block_given? == false
  yield(num, 2)
end

moko(1)
=> "block..."

moko(1) do |a, b|
  a + b
end
=> 3

Proc

別ページへ移動しました Proc

lambda

こちらもチェック Proc#procクラス以外の手続きオブジェクト

まずは普通にcallする、Procと特に違いは無いように見える

lmd = lambda { |a| p a }

# 1.9からの新記法
lmd = -> (a) { p a }

lmd.call(1)
1
=> 1

return時の振る舞いがProcと違う

# Proc
def moko
  proc = Proc.new do
    return 1
  end

  proc.call # returnで現在のスコープを脱出する この行にreturnが書いていたかのような動作
  2         # この行は実行されない
end

moko
#=> 1

# lambda
def moko
  lmd = -> do
    return 1
  end

  lmd.call # returnで脱出するのはProc(lambda)内の処理だけ
  2        # この行は実行される
end

moko
#=> 2

当然ながら、トップレベルでProc { return }すると戻り先が無いのでエラー

Proc.new { return }.call
LocalJumpError: unexpected return

# うう・・この動作はどう説明すればいい・・
def moko
  yield
end

moko do
  return
end
LocalJumpError: unexpected return