朝ニュースで横横道路が凍結のため全線通行止めということで、結局仕事を休みにしました。あちらこちらでスリップが原因の大きな事故がおきていたので、行こうと思えば下道で行けたと思うけど、多分行かなくて正解だったと思います。
さて、今日は午前中は部屋の掃除、午後はちょっと買い物に出かけましたが、かなりの時間をrubyの勉強に使いました。「たのしいruby」は、rubyの本の中ではかなりわかりやすいよい本(というか、rubyには、ほかの言語ほど丁寧な解説本はない)だと思うのですが、それでもかなり高度な本です。で、やっぱりどれだけできる人がわかりやすい本を書いても、残念ながらどうしても書き漏らしがあるようです。引っかかる部分って、人それぞれというのもあると思うのですが、たとえば、普通はこんな使い方をするんだけど、こんな使い方もある。だけど、一般的に解説されてない、といったようなケース。スクリプトを読んでいるうちに、ふとしたきっかけで気がつくこともありますが、どこかで解説してないと一生気がつかないかもしれないようなコードが書いてあったりして、かなり苦戦しています。
昨日から、郵便番号のcsvファイルを読み込んで、データベースを作成し、検索結果を表示するという事例に取り組んでいるのですが、こういうスクリプトが書いてあります。(「たのしいruby 第2版」p429より引用)
#jzipcode.rb
require “gdbm”
require “csv”
module JZipCode
COLUMN_ZIP = 2
ZIP_FILE = “ken_all.csv”
DB_FILE = “ken_all.db”
module_function
def make_database(zipfile,dbfile)
return if File.exist?(dbfile)
open(zipfile){|io|
GDBM.open(dbfile, 0644, GDBM::NEWDB){|db|
io.each{|line|
colums = line.split(“,”)
zipcode = colums[COLUMN_ZIP].delete(‘”‘)
if tmp = db[zipcode]
line = tmp + line
end
db[zipcode] = line
}
}
}
end
def find(code)
make_database(ZIP_FILE, DB_FILE)
GDBM.open(DB_FILE, nil, GDBM::READER|GDBM::NOLOCK){|db|
if line = db[code]
return CSV.parse(line)
end
}
return nil
end
end
問題は、赤字の部分です。どこにもtmpという変数は設定されておらず、いきなり現われたtmpとdb[zipcode]を比較して、条件分岐をしているように見えます。ここで昨日の夜からずっと悩んでいたのですが、どうやらここでのifは、「もし、db[zipcode]がnilでなかったら、tmpにdb[zipcode]を代入して、次の行を実行する。」というスクリプトのようです。何度もifのところを読み返してみたのですが、この使い方はまったく触れられていませんでした。このスクリプト、実は下の方にreturn nilという部分(緑)があって、ちょっと上のif line = db[code]のところで該当がないcodeを入力するとnilを返します。上の赤の部分は実はnilでない時のみ実行される部分で、通常は登録されていないzipcodeが与えられるので、この部分は実行されず、その下のdb[zipcode] = lineが実行されて、データベースにkey、valueの順にデータが登録されていくスクリプトなのです。
次のスクリプトはjzipcode.rbをモジュールとしてインクルードして実行するスクリプトです。
#test_jzipcode.rb(p433より引用)
require “jzipcode”
require “nkf”
t0 = Time.now
code = “2291133”
if rows = JZipCode.find(code)
rows.each{|row|
address = row[6] + row[7]
unless /^\210\310\211\272\202\311/ =~ row[8]
address << row[8]
end
puts NKF.nkf(“-s”, address)
}
end
p Time.now – t0
このスクリプトでも赤の部分でいきなりrowsという変数が現われています。これも、JZipCode.find(code)がnilでなければrowsに戻り値を代入するというケースです。
わかってしまえば、何のことはない。そんなスクリプトですが、これがわかるまでかなり苦労しました。プログラミングの世界は私にとって、ドラクエでいうと、最初のお城からようやくフィールドに出て歩き始めた、そんなところなのでしょう。レベルアップを図り、キメラやドラゴンと戦えるようになるのは、まだまだはるか遠い先の話のようです。果たしてすらいむ1号は勇者になれるのか?
コメント