たのしいRuby 第20章 イテレーター

会社の昼休みの読書に、プログラミングRuby言語編を読み始めました。この本メチャクチャ面白い!!詳しい言語リファレンスはもちろん、C言語Rubyインタプリタを組み込むといった高度な話題まで盛り沢山です。絶対買いの一冊です。

さて、いよいよ。Rubyの目玉機能、イテレーターに入ります。

とりあえず復習

ハッシュのvalue取り出しに、配列演算子を指定できる。

sum = 0
{"りんご" => 1 ,"バナナ" => 3,"パイナップル" => 4}.each do |key|
  sum += key[1]
end
puts sum #=> 8

eachでkeyのみを指定した場合、keyの中に配列ではいっているのを利用する。

わかりにくい・・・。

sortについて。

sortとsort_byでは呼び出し回数が違う。内部実装がちがうので、適切な方を選ぶべし。

sort_byはシュワルツ変換を用いている。perlの文献を読む必要アリ。

どうやら、テーブルを作ってからソートしているらしい。

初めてのPerlが面白そうです。買おうかなぁ・・・。

プログラミング言語Rubyライブラリ編からのHack

Dir["*"]

便利杉。

イテレーターの実装

ふぅ。かなり面倒だった。

#!/usr/bin/ruby -Ku

class Book
  attr_accessor :title, :author, :genre
  def initialize(title, author, genre=nil)
    @title = title
    @author = author
    @genre = genre
  end
  def inspect
    "#{@title}, #{@author}, #{@genre}"
  end

end

class BookList
  def initialize()
    @list = Array.new
  end
  def append(book)
    @list.push(book)
  end
  def length
    book.length
  end
  def inspect
    books = ""
    @list.each {|book| books += book.inspect + "\n"}
    books
  end
  def []=(n, book)
    @list[n] = book
  end
  def [](n)
    @list[n]
  end
  def delete(book)
    @list.delete(book)
  end
  def each
    @list.each do |book|
      yield(book)
    end
  end
  def each_title
    @list.each do |book|
      yield(book.title)
    end
  end
  def each_title_author
    @list.each do |book|
      yield(book.title, book.author)
    end
  end
  def find_by_author(author)
    if block_given?
      @list.each do |book|
        if book.author =~ author
         yield(book)
        end
      end
    else
      result = []
      @list.each do |book|
        if book.author =~ author
          result << book
        end
      end
      result
    end
  end
end

book_list = BookList.new
DATA.each do |line|
  book = Book.new(*line.split(" "))
  book_list.append(book)
end
book_list[0].title = "はじめてのPerl"
puts book_list[0].title

book_list.delete(book_list[0])

puts
book_list.each do |book|
  puts book.inspect
end

puts
book_list.each_title do |title|
  puts title
end

puts
book_list.each_title_author do |title, author|
  puts "#{title}, #{author}"
end

puts
p book_list.find_by_author(/達人/)

puts
book_list.find_by_author(/さん/) do |book|
  p book
end
__END__
はじめてのRuby              高橋さんと、後藤さん  Ruby
プログラミングRuby          達人プログラマーさん  Ruby
ふつうのLinuxプログラミング 青木さん              Linux
OS自作入門                  Kさん                 OS
  • book作成に__END__を使ってみた。かなり便利。
  • テストについて見直す必要が出てきた。
  • inspectを直接呼ばなければならない箇所がある。
  • yield,block_given?の説明があんまり詳しく載ってなかった。
  • 言語編には詳しく書いてあるけど、詳しすぎ。
  • 命名はCLUから取ったって書いてあるけど、CLUってなんだよぉぉぉ!!

ちょっと後味が悪い&課題いっぱい。

CLUについて調べてみた。

CLUが何なのかわからないとRubyを理解できない気がするので調べる。

Rubyist Magazine - Rubyist のための他言語探訪 【第 2 回】 CLU
概要はばっちり掴める。Rubyそっくりの文法。
CLU - Wikipedia
す、すげぇ。多重代入やら、例外処理やら。
第8章  オブジェクト指向言語百花繚乱 Smalltalk、LOGO、Flavors、Clu【言語】
歴史。
CLU HOME PAGE
処理系。マニュアルが面白い。makeは失敗orz
http://www2.latech.edu/~acm/helloworld/clu.html
そして、辿り着いたHello, World。

CLUはこんな感じ。色分けにRubyを指定してみた(笑

start_up = proc()
    outstream:stream := primary_output()
    for s:string in get_hello_world() do
        stream$putl(outstream,s)
      end
  end

get_hello_world = iter() yields(string)
    while (true) do
        yield ("Hello, World!")
      end
  end

めちゃめちゃRubyっすね!!

libcのバージョンが合わずコンパイルに失敗したけど、なんとなくCLUの感じは掴めたかな。やはり調べる価値アリでした。