まだまとまっていませんごめんなさい。

■ 文字列を

スクリプトを書いてとりあえず? 扱うことになるのは「文字列」です。 多くの処理では、テキストなどの文字列が対象になります。 便利な機能がいろいろありますので、活用しましょう。 ということで、ここでは文字列を扱う「String クラス」の話が中心になります。

■ 文字列って?

文字列は「"」または「'」で囲んだ文字列です。 次のような形式です。

$ irb
irb(main):001:0> str1 = "string 1"
"string 1"
irb(main):002:0> str2 = 'string 2'
"string 2"
irb(main):003:0> p str1
"string 1"
nil
irb(main):004:0> p str2
"string 2"
nil
irb(main):005:0> 
文字列自身がオブジェクトだということも覚えておいてください。 String クラスのメソッドを使って、文字列を直接操作することも可能です。
$ irb
irb(main):001:0> str = 'string'.upcase
"STRING"
irb(main):002:0> p str
"STRING"
nil
irb(main):003:0> 
「文字列」も、String クラスですから String クラスのメソッドで処理を行なうことが可能です。

■ 変数とオブジェクト

文字列操作を行っていると、直接オブジェクトを修正する場合があります。 このいいかたで、ピンっとくるかたは OK なのですが、まだなれていないかたは、ちょっとひっかかる場合があります。 変数が指し示すオブジェクトが操作の対象になりますが、同じオブジェクトを別の変数が指し示していることもあります。 オブジェクトへの直接の操作は、影響の範囲について気をつけてください。 次の例は、変数 ab に同じオブジェクト(「=」はコピーを生成するのではありません)を設定して、操作する例です。

$ irb
irb(main):001:0> a = "string"
"string"
irb(main):002:0> b = a
"string"
irb(main):003:0> p a
"string"
nil
irb(main):004:0> p b
"string"
nil
irb(main):005:0> a.upcase!
"STRING"
irb(main):006:0> p a
"STRING"
nil
irb(main):007:0> p b
"STRING"
nil
irb(main):008:0> p a.id
358785434
nil
irb(main):009:0> p b.id
358785434
nil
irb(main):010:0> 
このような直接オブジェクトを修正してしまうような(破壊的な)メソッドにはメソッド名に「!」がつく場合が多いです。 直接オブジェクトを修正してしまうということは、そのオブジェクトを参照している変数すべてに影響を与えます。 変数 a の文字列を変更したら、変数 b の文字列も修正されてしまいました。 変数 a も変数 b も Object#id で確認すると、同一オブジェクトであることがわかります。 最初は戸惑うと思いますが、「変数」は生成された「オブジェクト」に変数名でラベルをつけていると考えてみてください。 今回の例では、一つのオブジェクトに二つのラベルをつけたということになります。 いかがでしょうか?

ある変数(ここではあえて変数と書きますが)の内容を保存し、修正するつもりで次のように書くのは間違いになります。

backup = org
org.gsub!(/RUBY/, 'Ruby')
org の内容を保存するために backup へ代入しています。 でも、このときは、orgbackup も同じオブジェクトを示しています。 修正はどちらにも影響してしまいます。
$ irb
irb(main):001:0> org = "RUBY"
"RUBY"
irb(main):002:0> backup = org
"RUBY"
irb(main):003:0> org.sub!(/RUBY/, 'Ruby')
"Ruby"
irb(main):004:0> p org
"Ruby"
nil
irb(main):005:0> p backup
"Ruby"
nil
irb(main):006:0> p org.id
358785634
nil
irb(main):007:0> p backup.id
358785634
nil
irb(main):008:0> 
この方法では、変数 backup が示すオブジェクトも修正されてしまいます。 同じ目的には、
new_org = org.sub(/RUBY/. 'Ruby')
とすることで、新しいオブジェクトを作成して処理を行なうことが可能です。
$ irb
irb(main):001:0> org = 'RUBY'
"RUBY"
irb(main):002:0> new = org.sub(/RUBY/, 'Ruby')
"Ruby"
irb(main):003:0> p org
"RUBY"
nil
irb(main):004:0> p new
"Ruby"
nil
irb(main):005:0> p org.id
358785864
nil
irb(main):006:0> p new.id
358764764
nil
irb(main):007:0> 
または Object#dup や Object#clone で明示的に複製を作成してから処理を行なう方法もあります。
backup = org.dup
org.gsub!(/RUBY/, 'Ruby')
$ irb
irb(main):001:0> org = "RUBY"
"RUBY"
irb(main):002:0> backup = org.dup
"RUBY"
irb(main):003:0> org.sub!(/RUBY/, 'Ruby')
"Ruby"
irb(main):004:0> p org
"Ruby"
nil
irb(main):005:0> p backup
"RUBY"
nil
irb(main):006:0> p org.id
358785634
nil
irb(main):007:0> p backup.id
358770874
nil
irb(main):008:0> 
のように書くことになります。 直接オブジェクトを修正する方法ではなく、オブジェクトを操作した結果を新しいオブジェクトに格納すると、スムーズに書けるように思います。

String クラスの操作では、dup/clone でコピーが生成されてから「なになにの処理を行なう」というものもあります。

■ 文字列への演算子

+ で文字列を加える

「文字列」+「文字列」は、「文字列文字列」です。 一般の言語? は、文字列操作用の関数を持っていて文字列をつなぎ合わせます。

C 言語などは、文字列操作は専用の関数を使うことになります。 また、文字列用の特別な演算子を持っているものもあります。 Perl の「.」などです($a = $b . "string";)。
Ruby はオブジェクト指向スクリプト言語です。 String クラスで定義されているメソッドにより、「+」が適切な処理をしてくれます。
$ irb
irb(main):001:0> a = "abc" + "def"
"abcdef"
irb(main):002:0> a += "ghi"
"abcdefghi"
irb(main):003:0> 
残念ながら「-」はないのですが、sub が同じような意味で使われます(文字通り?)。 もし「a - b」が、文字列オブジェクト a から、文字列 b を削除するのでしたら次のようになりますね。
a.sub(b, '')
クラス定義してしまうと次のようになるのでしょうか?
class String
  def - (other)
    self.sub(other, '')
  end
end
$ irb
irb(main):001:0> class String
irb(main):002:1>  def - (other)
irb(main):003:2>   self.sub(other, '')
irb(main):004:2>  end
irb(main):005:1> end
nil
irb(main):006:0> a = "string"
"string"
irb(main):007:0> a - "str"
"ing"
irb(main):008:0> p a
"string"
nil
irb(main):009:0> 

■ メソッドの連続

オブジェクトである文字列に対して、連続してメソッドを適用することができます。 必要な処理をどんどんつなげて実行することができます。 次の例はファイルまたは 標準入力 から入力した漢字の文字列を NKF ライブラリで EUC Japan に変換し、「、」を「,」に「。」を「.」に変換しています。

#! /usr/local/bin/ruby -Ke
# /home/tetsu/src/ruby/intro/str1.rb
# Created: September 17,2000 Sunday 22:10:09

require 'nkf'

while gets
  print NKF.nkf('-eZ', $_).
    gsub(/、/, ',').
    gsub(/。/, '.')
end
このスクリプトは、EUC kanji コードでの実行を想定して、オプション -Ke になっています。 このスクリプトをファイルにセーブするときに EUC kanji コードにしてください。 または、-Ke オプションと NKF モジュールのオプション -e と、スクリプトファイルの漢字コードをあわせてください。 上記の例は、EUC kanji であわせたときのものです。
メソッドの連結(.)を使用し必要な処理を次々に行っています。 一気に処理することも可能ですが、今回はメソッドの連結の例のためにわけています。


渡辺哲也(WATANABE Tetsuya): Tetsuya.WATANABE atmark nifty.com