Design Pattern: Ruby Companion

4 Iterator ¥Ñ¥¿¡¼¥ó

4.1 Iterator¥Ñ¥¿¡¼¥ó¤Î°Õ¿Þ

(¤º¤Ð¤Ã¤Èά)

4.2 Iterator¥Ñ¥¿¡¼¥ó¤Î¼ÂÁõ

RubyÈǤǤϡ¤Á´¤Æ¤Î¥¯¥é¥¹ÄêµÁ¤È¥µ¥ó¥×¥ë¤ò1¤Ä¤Î¥½¡¼¥¹¤Ë¤Þ¤È¤á¤Æ¤¤¤Þ¤¹¡¥

4.2.1 ¥µ¥ó¥×¥ë¤½¤Î1: ÉáÄ̤μÂÁõ

ÁÇËѤËRuby¤Ç¼ÂÁõ¤·¤¿¤â¤Î¤Ç¤¹¡¥¥á¥½¥Ã¥É¤Ê¤É¤ÏRuby¤Ã¤Ý¤¯ÊѤ¨¤¿¤È¤³¤í¤â¤¢¤ê¤Þ¤¹¡¥

# Iterator Pattern
# sample1

class Book
  def initialize(name)
    @name = name
  end

  attr_reader :name
end

class BookShelf
  def initialize()
    @books = Array.new()
  end
  def [](index)
    return @books[index]
  end
  def append_book(book)
    @books << book
  end
  def length
    return @books.length
  end
  def iterator
    return BookShelfIterator.new(self)
  end
end

class BookShelfIterator
  def initialize(bookshelf)
    @bookShelf = bookshelf
    @index = 0
  end

  def has_next?()
    @index < @bookShelf.length
  end

  def next()
    book = @bookShelf[@index]
    @index += 1
    return book
  end
end

### main

if __FILE__ == $0
  bookShelf = BookShelf.new()
  bookShelf.append_book(Book.new("Around the World in 80 Days"))
  bookShelf.append_book(Book.new("Bible"))
  bookShelf.append_book(Book.new("Cinderella"))
  bookShelf.append_book(Book.new("Daddy-Long-Legs"))

  it = bookShelf.iterator()

  while it.has_next?
    book = it.next()
    print book.name, "\n"
  end
end

4.2.2 ¥µ¥ó¥×¥ë¤½¤Î2: ÆâÉô¥¤¥Æ¥ì¡¼¥¿

¡Ö¥µ¥ó¥×¥ë¤½¤Î1¡×¤Ï¡¤¥ª¥Ö¥¸¥§¥¯¥È¤ò³ÊǼ¤¹¤ë¥³¥ó¥Æ¥Ê¤È¡¤¥³¥ó¥Æ¥Ê¤ò¥¹¥­¥ã¥ó¤¹¤ë¥¤¥Æ¥ì¡¼¥¿¤È¤¬ÊÌ¡¹¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ë¤Ê¤Ã¤Æ¤¤¤Æ¡¤¥¤¥Æ¥ì¡¼¥¿¤òÁ°¤Ë¿Ê¤Þ¤»¤ë¤Ë¤Ï¤½¤ÎÅÔÅÙ next ¥á¥½¥Ã¥É¤ò¼Â¹Ô¤µ¤»¤ëɬÍפ¬¤¢¤ê¤Þ¤·¤¿¡¥

¤È¤³¤í¤Ç¡¤Ruby¤Ç¡Ö¥¤¥Æ¥ì¡¼¥¿¡×¤È¤¤¤¦¤È¡¤¤Õ¤Ä¤¦¤Ï¥µ¥ó¥×¥ë¤½¤Î1¤Î¤è¤¦¤Ê¤â¤Î¤Ç¤Ï¤Ê¤¯¡¤¥³¥ó¥Æ¥Ê¤È¥¤¥Æ¥ì¡¼¥¿¤È¤¬Æ±¤¸¥ª¥Ö¥¸¥§¥¯¥È¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤·¤Þ¤¹¡¥¤½¤·¤Æ¡¤¥¤¥Æ¥ì¡¼¥¿¤ò¿Ê¤Þ¤»¤ë¤¿¤á¤Î¥á¥½¥Ã¥É¤ÏɬÍפ¢¤ê¤Þ¤»¤ó¡¥¥¤¥Æ¥ì¡¼¥¿¤Ë¾¡¼ê¤Ë¿Ê¤Þ¤»¤ë¤Î¤Ç¤¹¡¥¤³¤Î¤è¤¦¤Ê¥¤¥Æ¥ì¡¼¥¿¤ò¡¤¡ÖÆâÉô¥¤¥Æ¥ì¡¼¥¿¡×¤È¸À¤¤¤Þ¤¹¡¥¤³¤ì¤ËÂФ·¤Æ¡¤¥µ¥ó¥×¥ë1¤Î¤è¤¦¤Ê¥¤¥Æ¥ì¡¼¥¿¤ò¡Ö³°Éô¥¤¥Æ¥ì¡¼¥¿¡×¤È¤â¸À¤¤¤Þ¤¹¡¥

Ruby¤ÎÆâÉô¥¤¥Æ¥ì¡¼¥¿¤ò»È¤Ã¤Æ¼ÂÁõ¤¹¤ë¤È¡¤°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡¥¥¤¥Æ¥ì¡¼¥¿¤Ïeach¥á¥½¥Ã¥É¤Ë¤è¤Ã¤Æ¼ÂÁõ¤µ¤ì¤Æ¤¤¤Þ¤¹¡¥

# Iterator Pattern
# sample2: using Enumerable

class Book
  def initialize(name)
    @name = name
  end

  attr_reader :name
end

class BookShelf
  include Enumerable

  def initialize()
    @books = Array.new()
  end

  def [](index)
    @books[index]
  end

  def <<(book)
    @books << book
  end

  def length()
    @books.length
  end

  def each()
    @books.each{|book|
      yield(book)
    }
  end
end

## main

if __FILE__ == $0
  bookShelf = BookShelf.new()
  bookShelf << Book.new("Around the World in 80 Days")
  bookShelf << Book.new("Bible")
  bookShelf << Book.new("Cinderella")
  bookShelf << Book.new("Daddy-Long-Legs")

  bookShelf.each{|book|
    print book.name, "\n"
  }

  bookstr =  bookShelf.collect{|book|
    '"'+book.name+'"'
  }.join(":")
  print bookstr, "\n"
end

4.2.3 ¥µ¥ó¥×¥ë¤½¤Î3: Struct¤ÈArray¤Î·Ñ¾µ

¥µ¥ó¥×¥ë¤½¤Î2¤ÎBookShelf¥¯¥é¥¹¤ÎÄêµÁ¤ÎÄ̤ꡤBookShelf¥¯¥é¥¹¤Ï¡¤·ë¶É¤Î¤È¤³¤í¤Û¤È¤ó¤ÉArray¥¯¥é¥¹¤ÈƱ¤¸µ¡Ç½¤ò»ý¤Ä¥¯¥é¥¹¤Ë¤Ê¤ê¤Þ¤¹¡¥¤½¤Î¤¿¤á¡¤¤¤¤Ã¤½¤Î¤³¤ÈArray¤ò¤½¤Î¤Þ¤Þ»È¤Ã¤Æ¤â¹½¤ï¤Ê¤¤¤Î¤Ç¤¹¤¬¡¤¤½¤¦¤¹¤ë¤Èº£ÅÙ¤ÏBookShelfÆȼ«¤Î¥á¥½¥Ã¥É¤òÄêµÁ¤Ç¤­¤Ê¤¯¤Ê¤ê¤Þ¤¹¡¥¤½¤³¤Ç¡¤Array¤ò·Ñ¾µ¤µ¤»¤¿¥¯¥é¥¹¤Ë¤·¤Æ¤ß¤Þ¤·¤ç¤¦¡¥

¤Þ¤¿¡¤Ã±¤Ê¤ë°À­¤ò»ý¤Ã¤¿¥ª¥Ö¥¸¥§¥¯¥È¤Î¥¯¥é¥¹¤¬¤Û¤·¤¤¾ì¹ç¤Ë¤Ï¡¤ Struct¥¯¥é¥¹¤ò»È¤¤¤Þ¤¹¡¥¤³¤ì¤Ï¡¤Ã±¤Ê¤ë°À­¤È¡¤¤½¤Î°À­¤Ø¤Î¥¢¥¯¥»¥¹¥á¥½¥Ã¥É¤Î¤ß¤Î¥¯¥é¥¹¤òºî¤ë¤¿¤á¤Î¥¯¥é¥¹¤Ç¤¹¡¥Struct.new¤Î·ë²Ì¤òÄê¿ô¤ËÂåÆþ¤¹¤ë¤Î¤¬¥ß¥½¤Ç¡¤¤½¤ÎÄê¿ô¤¬¿·¤·¤¤¥¯¥é¥¹¤Ë¤Ê¤ê¤Þ¤¹¡¥

# Iterator Pattern
# sample3: using Struct and inheretance of Array class

## Book class
Book = Struct.new("Book", :name)

## BookShelf class
class BookShelf < Array; end

## main
if __FILE__ == $0
  bookShelf = BookShelf.new()
  bookShelf << Book.new("Around the World in 80 Days")
  bookShelf << Book.new("Bible")
  bookShelf << Book.new("Cinderella")
  bookShelf << Book.new("Daddy-Long-Legs")

  bookShelf.each{|book|
    print book.name, "\n"
  }

  bookstr =  bookShelf.collect{|book|
    '"'+book.name+'"'
  }.join(":")
  print bookstr, "\n"
end

4.2.4 ¥µ¥ó¥×¥ë¤½¤Î4: Array¤Ø¤Î°Ñ¾ù(delegate)

·Ñ¾µ¤ÎÂå¤ï¤ê¤Ë°Ñ¾ù¤ò»È¤Ã¤Æ¤ß¤Þ¤·¤ç¤¦¡¥°Ñ¾ù¤ò»È¤¨¤Ð¡¤¥¯¥é¥¹¤ò·Ñ¾µ¤µ¤»¤ë¤³¤È¤Ê¤¯¡¤Â¾¤Î¥¯¥é¥¹¤Îµ¡Ç½¤òÍøÍѤǤ­¤Þ¤¹¡¥

# Iterator Pattern
# sample4: using delegate 

require 'delegate'

## Book class
Book = Struct.new("Book", :name)

## BookShelf class
class BookShelf < DelegateClass(Array)
  def initialize()
    super([])
  end
end


## main
if __FILE__ == $0
  bookShelf = BookShelf.new()
  bookShelf << Book.new("Around the World in 80 Days")
  bookShelf << Book.new("Bible")
  bookShelf << Book.new("Cinderella")
  bookShelf << Book.new("Daddy-Long-Legs")

  bookShelf.each{|book|
    print book.name, "\n"
  }

  bookstr =  bookShelf.collect{|book|
    '"'+book.name+'"'
  }.join(":")
  print bookstr, "\n"
end

4.2.5 ¥µ¥ó¥×¥ë¤½¤Î5: Array¤Ø¤Î°Ñ¾ù¤½¤Î2¡¦(forwarding)

Deletagor¤ò»È¤Ã¤¿¾ì¹ç¡¤¸µ¤Î¥¯¥é¥¹¤ÎÁ´¤Æ¤Î¥á¥½¥Ã¥É¤Ë¤Ä¤¤¤Æ°Ñ¾ù¤µ¤ì¤Æ¤·¤Þ¤¦¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡¥¤·¤«¤·¡¤¤½¤¦¤Ç¤Ï¤Ê¤¯¡¤¸Â¤é¤ì¤¿¥á¥½¥Ã¥É¤Ë¤Ä¤¤¤Æ¤Î¤ß°Ñ¾ù¤·¤¿¤¤¤³¤È¤â¿¡¹¤¢¤ê¤Þ¤¹¡¥

¤½¤Î¤è¤¦¤Ê¾ì¹ç¤Ë¤Ï¡¤forwardable¥é¥¤¥Ö¥é¥ê¤ò»È¤¤¤Þ¤¹¡¥¤³¤Á¤é¤Ï¡¤°Ñ¾ù¤·¤¿¤¤¥á¥½¥Ã¥É¤ò»ØÄꤷ¤Æ¤ª¤±¤Ð¡¤¤½¤Î¥á¥½¥Ã¥É¤Î¤ß°Ñ¾ù¤µ¤ì¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡¥

# Iterator Pattern
# sample5: using forwarding

require 'forwardable'

## Book class
Book = Struct.new("Book", :name)

## BookShelf class
class BookShelf
  extend Forwardable
  def_delegators("@books", "<<", "[]", "length", "each")

  include Enumerable

  def initialize()
    @books = Array.new()
  end
end


## main
if __FILE__ == $0
  bookShelf = BookShelf.new()
  bookShelf << Book.new("Around the World in 80 Days")
  bookShelf << Book.new("Bible")
  bookShelf << Book.new("Cinderella")
  bookShelf << Book.new("Daddy-Long-Legs")

  bookShelf.each{|book|
    print book.name, "\n"
  }

  bookstr =  bookShelf.collect{|book|
    '"'+book.name+'"'
  }.join(":")
  print bookstr, "\n"
end

4.3 ¤ª¤Þ¤±

»È¤¤Êý¤¬¸ÂÄꤵ¤ì¤Æ¤¤¤ëʬ¤Ë¤Ï¡¤³°Éô¥¤¥Æ¥ì¡¼¥¿¤è¤ê¤âÆâÉô¥¤¥Æ¥ì¡¼¥¿¤ÎÊý¤¬ÊØÍø¤Ç¤·¤ç¤¦¡¥¤¿¤À¤·¡¤Ê£»¨¤Ê»È¤¤Êý¤ò¤¹¤ë¾ì¹ç¤Ë¤Ï¡¤ÆâÉô¥¤¥Æ¥ì¡¼¥¿¤Ç´èÄ¥¤ë¤è¤ê¤Ï³°Éô¥¤¥Æ¥ì¡¼¥¿¤ò»È¤¤¡¤¼«Ê¬¤ÇÀ©¸æ¤·¤¿Êý¤¬¥·¥ó¥×¥ë¤Ë¤Ê¤ê¤½¤¦¤Ç¤¹¡¥

4.4 ¥½¡¼¥¹

¸Ç¤á¤Æ¤ª¤­¤Þ¤·¤¿¡¥¤³¤Á¤é¤«¤é¤É¤¦¤¾¡¥

<URL:src-iterator.tar.gz>

4.4.1 ¥½¡¼¥¹¤Î¥é¥¤¥»¥ó¥¹

¤³¤Î¥½¡¼¥¹¤Ï¡¤·ë¾ë¹À¤µ¤ó¤Ë¤è¤ë¡ØJava¸À¸ì¤Ç³Ø¤Ö¥Ç¥¶¥¤¥ó¥Ñ¥¿¡¼¥óÆþÌç¡Ù¤ò¸µ¤Ë¡¤¤¿¤«¤Ï¤·¤¬ RubyÍѤ˼ê¤òÆþ¤ì¤¿¤â¤Î¤Ç¤¹¡¥Ruby¤È¤·¤Æ¼«Á³¤Ê¥½¡¼¥¹¤Ë¤¹¤ë¤è¤¦¤Ë¤·¤¿¤¿¤á¡¤¤¢¤ó¤Þ¤ê¸¶·¿¤òα¤á¤Æ¤Þ¤»¤ó¡¥

¥ª¥ê¥¸¥Ê¥ë¤Î¥½¡¼¥¹¤Î¥é¥¤¥»¥ó¥¹¤Ï¡¤ <URL:http://www.hyuki.com/dp/index.html#download> ¤Ë¤¢¤ê¤Þ¤¹¡¥¤³¤Î¥½¡¼¥¹¤Î°·¤¤¤â¾åµ­¤ÈƱÍͤǤª´ê¤¤¤·¤Þ¤¹¡¥

ʸÀÕ: ¤¿¤«¤Ï¤·([email protected])