rubyベストプラクティスchapter7.4
とりあえず写経。。。
読み込みを色々な文字にしたり、読み込むバイトを色々変えてやってみる。
元はこれ
File.open("./hello.txt") { |f| loop do break if f.eof? chunk = "CHUNK: #{f.read(5)}" #ここの5を色々変える puts chunk unless chunk.empty? end }
で読み込むhello.txtを
hello
にした時
ruby read_hello.rb CHUNK: hello CHUNK:
まぁあたり前です。
read(3)にした時
ruby read_hello.rb CHUNK: hel CHUNK: lo
これもまぁ当り前
次はhello.txtを
こんにちわ
にした時
ruby read_hello.rb CHUNK: こ CHUNK: �に CHUNK: ��わ CHUNK:
おぉ!なんか変だ!
次はread(3)にする。
ruby read_hello.rb CHUNK: こ CHUNK: ん CHUNK: に CHUNK: ち CHUNK: わ CHUNK:
ちょっと脱線。
本でいいたいのはマルチバイトのエンコーディングの場合単純に2バイト1文字とか決めうちできないってこと。
そういうことを前提として1文字をどのように特定しているのかっていうのをcsvライブラリのソースで説明している。
def read_to_char(bytes) return "" if @io.eof? data = @io.read(bytes) begin encoded = encode_str(data) railse unless ecnoded.valid_encoding? #(1) return encoded #(3) rescue if @io.eof? or data.size >= bytes + 10 #(4) return data else #(2) data += @io.read(1) retry end end end
@ioってインスタンス変数がチャンク化したい文字のかたまり(csvライブラリではなんらかのioオブジェクト)で、
指定バイト数分読み込んだ文字列が文字として有効かっていうのをvalid_encoding?で確認している。(1)
有効な文字列でない場合、読み込みバイト数を1つ増やしてもう一度有効な文字列かを確認する。(2)
有効な文字列の場合その文字列を返す。(3)
文字列の塊(@io)が終端にたっするか、読み初めて10バイトを越えた場合はそこまで読み込んだ文字列を返す。(4)
データをチャンク化したい場合は
1. 1バイトずつ文字列を読んでいって
2. 読み込んだものをvalid_encoding?で有効な文字列かを確認して
3. 有効でない場合、さらに1バイト先まで読み込んで1-2をやりなおし。
4. 有効な文字列の場合それが返却値
といった流れになると思われます。
Rubyベストプラクティス -プロフェッショナルによるコードとテクニック
- 作者: Gregory Brown,高橋征義,笹井崇司
- 出版社/メーカー: オライリージャパン
- 発売日: 2010/03/26
- メディア: 大型本
- 購入: 9人 クリック: 307回
- この商品を含むブログ (43件) を見る