yieldがよくわからないのでspecで試しつつ確認してみた

yieldはブロックを引っ張るときに便利な機能……らしいです。
残念ながら、私のトリ頭では説明だけ読んでも全く理解できませんでした。
というわけで、rspecの練習がてら色々弄り倒してみる事にしました。
名称が色々アレなのはご愛嬌……

スクリプト

class TestClass
  def testFunc
    yield 10
  end

  def testFunc2
    yield "hogehoge"
  end

  def testFunc3
    yield 10, 100
  end

  def testFunc4(a)
    return 10 if a == :shuzo
    yield 0
  end

  def self.file(fname)
    fp = File.open(fname,"r") 
    yield fp
    fp.close
  end

  def each
    array = @str.split('')
    while e = array.shift
      key,value = e.split('は、')
      yield key,value
    end
  end

end

テスト

require 'rubygems'
require 'rspec'

require_relative 'test'

describe "What's a yield" do

  before :each do
    @hoge = TestClass.new
  end

  it 'return 10' do
    @hoge.testFunc do |i| i * 30 end.should == 10 * 30
  end

  it 'return hogehoge' do
    @hoge.testFunc2 do |i| i end.should == 'hogehoge'
  end

  it 'return [10,100]' do
    @hoge.testFunc3 do |i,j| [i * 9, j] end.should == [90,100]
    @hoge.testFunc3 do |i,j| i * j end.should == 1000
  end

  it 'return 0' do
    @hoge.testFunc4(:shuzo) do |i| i end.should == 10
    @hoge.testFunc4(:vivit) do |i| i end.should == 0
  end

  it 'fileをひらく&閉じる' do
    TestClass.file('test.log') do |i| i.class.should == File end
  end

  it '文字列を切り分ける' do
    @hoge.str = "ぼくは、きの。あなたは、しゅうぞう"
    debug_ary = []
    @hoge.each do |key,val|
      debug_ary << "#{key} : #{val}"
    end
    debug_ary.should == ["ぼく : きの","あなた : しゅうぞう"]
  end

end

まとめ

  • ブロックがある場合とない場合でロジックを切り分ける事が可能
  • selfと組み合わせれば、自前のインスタンスを使い終わり次第片付ける*1
  • 似非DSLを作って遊ぶときにも重宝?

*1:テストではFileクラスを呼び出しましたが、自クラスを呼び出す事も可能です。