カテゴリー「Ruby」の3件の記事

Rubyインタプリタに文字コードを指定するオプションをつける

Rubyではプログラム実行の結果による出力の文字コードを以下のようにいろいろ指定できるようです。メール送信プログラムを書いていて厳密な文字コードの取り扱いが必要になり、初めて知りました。

#!/usr/local/bin/ruby
puts $KCODE       #=> NONE

#!/usr/local/bin/ruby -Ku
puts $KCODE       #=> UTF8

#!/usr/local/bin/ruby -Ke
puts $KCODE       #=> EUC

#!/usr/local/bin/ruby -Ks
puts $KCODE       #=> SJIS

rewind

Rubyで二重のループ処理をしようとしたときにうまく行きませんでした。そのときのソースは以下の通りです。(分かりやすく内容を少し変更してあります)

----------------------------------------------
#!/usr/local/bin/ruby

afile = "a.txt"
bfile = "b.txt"

aFH = File.open(afile, "r")
bFH = File.open(bfile, "r")

aFH.each do |aline|
  puts "aaa"
  bFH.each do |bline|
    puts "bbb"
  end
end

bFH.close
aFH.close

----------------------------------------------

この結果を

aaa

bbb

bbb

bbb

aaa

bbb

bbb

bbb

aaa..

のようになることを期待したのですが、実際の結果は

aaa

bbb

bbb

bbb

aaa

aaa

aaa

aaa..

のようになりました。

あれ?2個目のネストのループ処理が一回で抜けてしまっている?と思い、いろいろ調べたところ、ファイルハンドルをeachなどで一行ずつ処理すると、ポインタがファイルの最後の部分で保存されてしまい、その後何回処理が走っても一行もヒットしなくなってしまうようです。

これに対応するためにあるのがrewindというメソッドです。これはポインタの位置をファイルの先頭に戻します。以下のようにプログラムに追記すれば期待した結果を得ることができました。

----------------------------------------------
#!/usr/local/bin/ruby

afile = "a.txt"
bfile = "b.txt"

aFH = File.open(afile, "r")
bFH = File.open(bfile, "r")

aFH.each do |aline|
  puts "aaa"
  bFH.each do |bline|
    puts "bbb"
  end
 bFH.rewind
end

bFH.close
aFH.close

----------------------------------------------

これはファイルハンドルでのみ起こる事で、例えば配列に対して同じ二重ループを実行する場合はrewindは必要ありません。

ちなみにPerlを主に使っていたときは、こんな部分に引っかかったことはなかったので、一応試してみたところ、Perlでもファイルハンドルを一行ずつ読み込んだ後はポインタがファイルの一番最後で止まったままになってました。あれー?

どうも無知過ぎていけません。

Rubyの破壊的メソッド

Rubyには破壊的メソッドというものがあります。この破壊的メソッドと通常のメソッドで何が違うのかを記述しようと思います。

例えば「chomp」という改行削除メソッドの破壊的メソッドは「chomp!」となります。

このように破壊的メソッドの形式は、通常のメソッドに!を付けたものになります。実際に、動きを見てみると、以下のようになっています。

--通常----------------------------------------
#!/usr/local/bin/ruby

data1 = "abc\n"
data2 = data1.chomp

p data1
p data2

> "abc\n"
> "abe"

----------------------------------------------

--破壊的---------------------------------------
#!/usr/local/bin/ruby

data1 = "abc\n"
data2 = data1.chomp!

p data1
p data2

> "abc"
> "abc"

----------------------------------------------

このように、元の変数(オブジェクト)の値を変更してしまうのが”破壊的”メソッドになります。