まだまとまっていませんごめんなさい。
スクリプトを書いてとりあえず? 扱うことになるのは「文字列」です。 多くの処理では、テキストなどの文字列が対象になります。 便利な機能がいろいろありますので、活用しましょう。 ということで、ここでは文字列を扱う「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 なのですが、まだなれていないかたは、ちょっとひっかかる場合があります。
変数が指し示すオブジェクトが操作の対象になりますが、同じオブジェクトを別の変数が指し示していることもあります。
オブジェクトへの直接の操作は、影響の範囲について気をつけてください。
次の例は、変数 a と b に同じオブジェクト(「=」はコピーを生成するのではありません)を設定して、操作する例です。
$ 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 へ代入しています。
でも、このときは、org も backup も同じオブジェクトを示しています。
修正はどちらにも影響してしまいます。
$ 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 の「Ruby はオブジェクト指向スクリプト言語です。 String クラスで定義されているメソッドにより、「.」などです($a = $b . "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 であわせたときのものです。
.)を使用し必要な処理を次々に行っています。
一気に処理することも可能ですが、今回はメソッドの連結の例のためにわけています。