添付ライブラリ: テキスト編
StringIOと呼ばれるクラスは、インスタンスの生成時に与えられた文字列やputs
で与えらた文字列を「バッファ(変数)」に格納し、またバッファに入った文字列をgets
やreadline
で読み込むことが出来る。
バッファと聞いて、特殊な仕組みが裏にあると思いきや、文字列の変数のことらしい。 それぞれ、Dirクラスのように読み込みモード、書き込みモード、読み書きモードなどが存在する。
StringIO.new
でインスタンスを生成できるが、new
に代わって open
を利用すると、ブロック内だけで、インスタンスの操作が可能になる。インスタンスの内容はブロックの一番最後の評価に書き換わる。
[16] pry(main)> sio = StringIO.open "HelloWorld" do |io| [16] pry(main)* "Yeah" [16] pry(main)* end => "Yeah" [17] pry(main)> p sio "Yeah" => "Yeah"
一方バッファへの書き込みは一文字書き込みの putc
と文字列に改行を付加して書き込むputs
と改行を付加しない`print
、フォーマットに従って書き込みを行うprintf
がある。
puts
は配列が引数に指定された場合は、各配列を連結して、それぞれに改行を付与する。
[18] pry(main)> sio = StringIO.new => #<StringIO:0x00007fffcb3909e0> [19] pry(main)> sio.puts "Hey siri" => nil [20] pry(main)> sio.string => "Hey siri\n" [21] pry(main)> sio.putc "ABCD" => "ABCD" [22] pry(main)> sio.string => "Hey siri\nA" [23] pry(main)> sio.string = "" => "" [24] pry(main)> sio.putc "ABCD" => "ABCD" [25] pry(main)> sio.string => "A" [26] pry(main)> sio.puts(["tokyo","shinagawa","shinyokohama"]) => nil [27] pry(main)> p sio #<StringIO:0x00007fffcb3909e0> => #<StringIO:0x00007fffcb3909e0> [28] pry(main)> sio.string => "Atokyo\nshinagawa\nshinyokohama\n"
一方、バッファからの読み込みはread
、readchar
、readline
がある。
read
の場合は引数に指定した数字だけバッファからの読み取りを行い、ポインタはその分だけ先に進む。
[32] pry(main)> sio.string => "Melbourne Australia VIC\n" [33] pry(main)> sio.read 3 => nil [36] pry(main)> sio.pos = 0 => 0 #ポインタの移動を行う [37] pry(main)> sio.read(3) => "Mel" [38] pry(main)> sio.read(1) => "b" [39] pry(main)> sio.read(1) => "o" [40] pry(main)> sio.read(10) => "urne Austr" [41] pry(main)> sio.read(20) => "alia VIC\n" [42] pry(main)> sio.read => "" [43] pry(main)> sio.read(100) => nil
また、第二引数に変数が指定されている場合、その変数に読み取った文字が格納される。
[48] pry(main)> var = "" => "" [49] pry(main)> sio.read(10,var) => "Melbourne "
さらに引数を省略すれば、ポインタの現在の位置から末尾までの文字が読み取られる。
[49] pry(main)> sio.read(10,var) => "Melbourne " [50] pry(main)> sio.read() => "Australia VIC\n"
ポインタが末尾まで到達しているのに、引数に数字を指定するとnil
が返ってくるが、この状態で引数を省略すると 空文字列
になる。
[51] pry(main)> sio.read() => ""
getcとreadcharはどちらも同じ、「一文字読み取り」のメソッドだが、 readchar
に限っては末尾まで到達すると、例外が発生する。一方、getc
の場合は空文字列ではなくnil
となる。
gets
や```readline````の場合は一行単位の読み取りを行う。末尾に到達したときの挙動はreadlineがreadcharと同じく例外である。
ポインタの移動はDirクラスのファイルポインタ移動と似ている。
pos
のほかにオフセットで指定した場所からの距離を数値で指定して移動することもできる。
[3] pry(main)> sio.string = "ABCDEFGHI" => "ABCDEFGHI" [4] pry(main)> sio.seek(3,IO::SEEK_SET) => 0 [5] pry(main)> sio.read => "DEFGHI"
この他にもオフセットはIO::SEEK_CUR
とIO::SEEK_END
が用意されている。