昨日の夜勤から、今の今までずっと悩んでいた。
以下はたのしいRuby 第2版 Rubyではじめる気軽なプログラミングのp154にあるwc.rbであるのだが、
#### wc.rb #####ltotal=0
wtotal=0
ctotal=0ARGV.each{|file|
begin
input = open(file)
l=0
w=0
c=0while line = input.gets
l += 1
c += line.size
line.sub!(/^\s+/,"")
ary = line.split(/\s+/).size #*1.原文ママ
w += ary.size #*2.だからここで悩んだ
endinput.close
printf("%8d %8d %8d %s\n",l,w,c,file)
ltotal += l
wtotal += w
ctotal += c
rescue => ex
print ex.message, "\n"
end
}printf("%8d %8d %8d %s\n",ltotal,wtotal,ctotal,"total")
##[EOF]
例外処理云々じゃなくて、*印のところで頭を抱えた。
ary = line.split(/\s/).size ##*1ってのは文字列 line を split メソッドにより空白で分割する。そして line は文字列オブジェクトを格納する配列となる。
んで、 size がインデックス数を返し、変数 ary に代入されるわけだしょ。うんそれはわかる。でもね、
w += ary.size ##*2
そうすっとこりゃなんじゃ?line.split(/\s/).size.sizeってこと?んー意味不明。
ここで得たいのは単語数なのであるから、文字列を、空白文字区切りにすると(配列の)要素がいくつできるかってことだよね。
line.split(/\s/).size
で既に欲しい数値はでてるわけだから直接、
w += line.split(/\s/).size
しちゃえばいいのに。 ary がなんのためにいるの?
すっげえ気になるからこんなの書いてみた。
#### test.rb ####file=ARGV[0]
input=open(file)while line = input.gets
line.sub!(/^\s+/,"")
ary = line.split(/\s+/).size
ary2 = ary.size
print "line.sub!#=>",line,"\n"
print "line.split.size#=>",line.split(/\s+/).size,"\n"
print "ary.size#=>",ary.size,"\n"
print "ary2#=>",ary2,"\n"
print "ary2.size#=>",ary2.size,"\n"
print "=========================\n"
end
input.close##[EOF]
これ引数をファイル名にして実行してみるとわかると思うんですが、
- ary.size
- ary2
- ary2.size
全部返す値が一緒になります。ずっと。
ary2 = ary.size
してるから一緒なのはわかるけどずっと同じ値を返すのはちょっとなんでかなって思う。
で調査したところ、
Array#size の size ってことは 整数n.size てことですわな。
でこれまた irb かなんかでやってみてもらえればわかると思うんですが、
4.size も 100.size も 100000.size も全部 4 を返します。
じゃあ 1000000000000000000.size も 4 かっていうとそれは違って 8 になります。
irb(main):070:0> 4294967295.size
=> 4
irb(main):071:0> 4294967296.size
=> 8
が分かれ目みたいですよ。
でやっとこさRubyリファレンスマニュアル - Rubyリファレンスマニュアルを調べる。
Integer - Rubyリファレンスマニュアルによると、
- size
整数の実装上のサイズをバイト数で返します。
現在の実装では Fixnum は、sizeof(long) 固定(多くの 32 bit マシンで 4 バイト)、Bignumは、システム依存です。
だそうな。実装上のサイズっていうのが雰囲気でしかわからんのだけど、
「まあ 4 は 100 より少ないけど、だからって紙に書くときインクの量が 1/25 ですむってわけでもないよね」って感じかな。
ふーん。これはこれで勉強になった。いやしかし、じゃあ wc.rb のあれはいったい。
てなとこで見つけましたよ。
サンプルのバグ発見してしまった・・・サイズの処理が間違ってる。『たのしいRuby 第2版』正誤表 次の版では直っているそうです。サポートページをブクマしとこう。
正誤表ブックマークさせていただきましたともさ。
LPIC-1 といい Ruby といい wc は鬼門だ。
(Linux 教科書 LPICレベル1 第3版(CD-ROM付) (Linux教科書)
では修正されているが、第2版では テキスト処理フィルタの項で、 wc の説明が、表示結果とそぐわない部分があった。)
トラックバック(0)
このブログ記事を参照しているブログ一覧: Ruby / これははまった / たのしいRuby-第9章
このブログ記事に対するトラックバックURL: http://jippenshar.com/igc/mt/mt-tb.cgi/109


コメントする