Ruby / これははまった / たのしいRuby-第9章

| | コメント(0) | トラックバック(0)

昨日の夜勤から、今の今までずっと悩んでいた。
以下はたのしいRuby 第2版 Rubyではじめる気軽なプログラミングのp154にあるwc.rbであるのだが、

#### wc.rb #####

ltotal=0
wtotal=0
ctotal=0

ARGV.each{|file|
    begin
        input = open(file)
        l=0
        w=0
        c=0

        while line = input.gets
            l += 1
            c += line.size
            line.sub!(/^\s+/,"")
            ary = line.split(/\s+/).size        #*1.原文ママ
            w += ary.size                            #*2.だからここで悩んだ
        end

        input.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

コメントする

このブログ記事について

このページは、YNが2008年1月28日 11:11に書いたブログ記事です。

ひとつ前のブログ記事は「Ruby技術者試験はプロメトリック社による実施へ-CodeZineより」です。

次のブログ記事は「Samba はやっぱり有線で接続 / 『君の席』をみてた / おぎやはぎ-小木はすげえ」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

フィードメーター - 十返舎.com あわせて読みたいブログパーツ
QLOOKアクセス解析
Powered by Movable Type 4.22-ja

Firefox3 Meter