tsucchi’s diary(元はてなダイアリー)

はてなダイアリー(d.hatena.ne.jp/tsucchi1022)から移行したものです

「初めての Ruby」一人勉強会(5日目)

昨日はサボってしまいましたが、Ruby をぼちぼち勉強しています。


教材はコレ↓
初めてのRuby


今日も第4章。文字列

これを読みつつ、つぶやいてみます。

以下、つぶやきメモ。

※1 今のところ、正直あまり Ruby は好きではありません。
※2 オイラがまともにそこそこ書ける言語は C#, Java(5.0より前), Perl です。言語の機能を語っているときはその辺との比較になっているはず
※3 Ruby はまだほとんど理解していないので、的外れでトンチンカンな批判してるかも
※4 コードはサンプルそのままのときと、オイラが勝手に変えてるときがあります

比較 (p.72 例4-17)
% irb
irb(main):001:0> "add" <=> "acc"
=> 1

コンテキスト毎に、良くも悪くも「いいように何とかしてくれる」 Perl と違い、to_s とか to_i とかで明示的に型変換がいるのが Ruby。ここは Perl だと、cmp 演算子で「文字列の比較」であることを明示しなきゃダメな局面だけど、Ruby だと文字列型だって分かっているので、スペースシップ演算子で比較できるらしい。これは便利だねぇ。('<' とかについても同様)

String の %演算子 (p.74 例4-21)
% irb
irb(main):001:0> "%0.4d" % 3
=> "0003"
irb(main):002:0> "%08.4f" % (Math::PI*10)
=> "031.4159"
irb(main):004:0> "hex=%X, oct=%o" % [10, 10]
=> "hex=A, oct=12"

ヒアドキュメントが出てきたときに疑問だった String の % 演算子。やっぱり sprintf のショートカット的使い方らしい。配列を渡せば複数の値も渡せるのかな。

シンボル (p.75 例4-24)

文字列リテラルの前にコロン(:)を付けるとシンボル。文字列だけど、変更不可で一意らしい。とりあえず「ハッシュキーに使う」ってだけ押えておけば当面は良いのかなぁ。

% irb
irb(main):001:0> symbol1 = :"ruby"
=> :ruby
irb(main):002:0> symbol2 = :"ruby"
=> :ruby
irb(main):003:0> symbol1 == symbol2
=> true
irb(main):004:0> symbol1.equal? symbol2
=> true
$KCODE (p.77)

前に、EUC の文字列入れたら、バイトが見えてびっくりしたけど、これは $KCODE という変数が正しく設定されていなかったのが原因らしい。

% irb
irb(main):001:0> puts $KCODE
NONE
=> nil
irb(main):002:0> str = "日本語だぜ"
=> "\306\374\313\334\270\354\244\300\244\274"
irb(main):003:0> puts str.inspect
"\306\374\313\334\270\354\244\300\244\274"
=> nil
irb(main):004:0> $KCODE='euc'
=> "euc"
irb(main):005:0> puts str.inspect
"日本語だぜ"
=> nil
irb(main):006:0> puts str
日本語だぜ
=> nil

$KCODE に euc を入れたら化けなくなった。

正規表現の日本語 (p.78 例4-28)
% irb
irb(main):001:0> regexp = /(.)/s
=> /(.)/s
irb(main):002:0> str = "\202\240"
=> "\202\240"
irb(main):003:0> regexp =~ str
=> 0
irb(main):004:0> p $1
"\202\240"
=> nil
irb(main):005:0> regexp = /(.)/n
=> /(.)/n
irb(main):006:0> regexp =~ str
=> 0
irb(main):007:0> p $1
"\202"
=> nil

正規表現に s オプションを付けると SJIS モードで n だとバイト列モードらしい。(n/s/e/u) が指定可。文字コードを考慮しつつ正規表現処理ができるらしい。

1.8 の憂鬱
% irb
irb(main):001:0> str = "日本語だぜ"
=> "\306\374\313\334\270\354\244\300\244\274"
irb(main):002:0> str.encoding
NoMethodError: undefined method `encoding' for "\306\374\313\334\270\354\244\300\244\274":String
        from (irb):2
        from :0
irb(main):003:0> Encoding.name_list
NameError: uninitialized constant Encoding
        from (irb):3
        from :0

Ruby 1.9 では文字列自身がエンコーディングを知っているらしいし、Perl の Encode モジュールみたいな Encoding クラスなんてのもある。でも 1.8 だと上のような残念な結果に...

1.9 だとマルチリンガル環境でもかなり大丈夫そうな感じ。(でも手元に試せる環境がない orz)


やっと 4章終了。文字列処理は LL のメインテーマだから比較的分量が多かったのと、あまり時間が取れなかったこともあって長引いてしまったなぁ。

5章に続く(多分)