コンテナ、ブロック、イテレータ(1) 「プログラミング Ruby 1.9 - 言語編 - 4章」

4章は配列、ハッシュのデータ集合とイテレータ構文について。

プログラミングRuby 1.9 −言語編−

プログラミングRuby 1.9 −言語編−

文字列や数値などのオブジェクトの説明の前に
データの「入れ物」とその操作方法から先に説明しちゃうところが面白いところ。
# 前の章で「変数」は説明済みなんですけどね。

あわせてブロック構文が当たり前に出てくるのが素敵。
構成が巧いなーと思っちゃいます。

配列とハッシュ


配列:

整数インデックスによるオブジェクト参照のコレクション。

ハッシュ:

連想配列、マップ、ディクショナリと呼ばれることも。任意のオブジェクトでインデックス付けできるコレクション。1.9から並び順も記録される。


配列とハッシュの区別が明確で、また、その大きさが可変なところがポイント。

Ruby 1.9からはシンボルをキーとした場合

{dog: 'canine', cat: 'feline', donkey: 'asinine'}

と書けるので "=>"を省略可能。# コロンの位置が逆だよっ!とtypoしそうなのはご愛嬌 :-p

「単語の出現回数を調べる」というパートは長いので割愛。
配列とハッシュの便利なメソッドを試して、しかもTestUnitにまで触れられているので
これから先の見通しがつくサンプルでした。

ブロックとイテレータ

不自然なforループよりeachメソッドを使いましょうね、という話から入ります。

ダメコード

for i in 0...5
  puts "#{top_five[i][0]}: #{top_five[i][1]}"
end

ベター

top_five.each do |word, count|
  puts "#{word}: #{count}"
end
# puts top_five.map{|word, count| "#{word}: #{count}"}

mapを使ってよりコンパクトに書くかどうかは好みの問題、とばっさり。

スコープの問題

ruby 1.8までは、同一スコープ内で、
ブロック内外に同名の変数が出現していると同じ変数と見なされてました。
また、ブロック内にのみある変数はブロック外で操作できません。

value = "some value"
sum = 0
[1,2,3,4].each{|value| sum += value}
p sum #=> 10
p value #=> 4


ruby 1.9からは、ブロック引数に渡した変数は
常にローカル変数(ブロック内ローカル)になったようです。

... 上と同じコード ...
p value #=> "some value"

また、ブロック引数の頭にセミコロンを付けるとローカル変数扱いになるそうです。

square ="some shape"; sum = 0
[1,2,3,4].each do |value; square|
  square = value * value
  sum += square
end
puts square #=> some shape

*1

長くなってきたので
以降のイテレータの実装については次のエントリに!

おまけ

メソッドの一覧はirb上では

> Array.methods

なんて調べて試せます。

リファレンスが欲しければ「るりま」のコマンドライン版を入れておけばめっちゃ便利です。

$ gem install myrurema
$ rurema --init
$ 
$ rurema Array
class Array < Object

include Enumerable

配列クラスです。
配列は任意の Ruby オブジェクトを要素として持つことができます。

一般的には配列は配列式を使って

  [1, 2, 3]

のように生成します。

*1:不要な一時変数... なのは例なのでご愛嬌