2009年
11月
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30

setup diary

2007|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|06|08|11|
2015|01|02|03|04|05|06|07|08|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|09|10|11|

2009-11-09 methodの途中の作業

_ yieldを使う

rubyであるメソッドの途中で別の作業をしたいときに、その内容をブロックとして与えて、yieldで実行することができる。ブロックを与えないときには何もしないのかと思いきや、エラーが起こるので、yield if block_given?としておけば良い。

問題なのは、いくつかの操作をメソッドの途中でしたいときだ。ブロックは二つ与えられないしと思っていたら、こんな感じで実現できることに気がついた。

def test
  puts 0
  yield(0) if block_given?
  puts 1
  yield(1) if block_given?
  puts 2
end
test{|i|
case i
when 0; puts 'a'
when 1; puts 'b'
end
}
test{ puts 'a' }
test
これで、ブロックを付けなくてもエラーが出ないし、場合分けがあるかも意識しないでも良い。

しかし、手続オブジェクトを引数に使うと、複数の手続を指定できるので、素直に書ける。

def test(a=nil,b=nil)
  puts 0
  a.call if a
  puts 1
  b.call if b
  puts 2
end
a=Proc.new{ puts 'a' }
b=Proc.new{ puts 'b' }
test(a,b)
test(a)
test()
しかし、メソッドを呼び出す前に手続オブジェクトを定義しないといけないので、少し面倒な気がする。間をとって、こんな感じが使い易いのかも知れない。
def test(a=nil)
  puts 0
  a.call if a.class==Proc
  puts 1
  yield if block_given?
  puts 2
end
test(Proc.new{ puts 'a' }){ puts 'b' }
test{puts 'b'}
test()
一つのブロックなら普通に書けて、二つ以上の場合には、少し冗長になる。