青木です。

  In mail "[ruby-dev:23139] backslash in string"
    Jun Adachi <adachi / jun.email.ne.jp> wrote:

> 安達@沖データと申します。

> (1) 無意味なバックスラッシュを入れると数が合わない?
> 
> irb(main):010:0> " \ab\de\ff"
> => " \abde\ff"
> 
> これって、" abdeff"か" \ab\de\ff"かのどちらかになって欲しい気がします。
> もちろんlengthで数えると長さは7です。

これは仕様通りです。\a と \f は正しいバックスラッシュ記法なので
それぞれベルと改ページに変換される。\d は正しくないので「d」
そのものになる。


> (2) gsubが正しく動いていない???

> irb(main):002:0> " \\ab\\de\\ff".gsub(/\\([a-f][a-f])/o, "\\1".to_i(16).chr)
> => " \000\000\000"
> 
> これは、おかしい。

gsub は普通のメソッドですから、引数が gsub に渡るまえに
変形してしまっては意味がありません。"\\1".to_i(16) は 0 です。

ブロックのあり・なしだけだと「似たようなもん」だと思ってしまうん
ですが、実際のところ、ブロック付き gsub とブロックなし gsub は
別のメソッドと思ったほうがいいです。この違いにはまる人があまりに
多すぎる。

個人的には以下のように使い分けます。

  * 固定文字列に置換するときは常にブロックなし sub / gsub
  * 可変の文字列に置換するときは常にブロック付き sub / gsub

例えば gsub(/\s+/, "") みたいなのは常にブロックなし。
「\1」や「\&」が出てきそうになったら迷わずブロックを使う。


> irb(main):003:0> " \\ab\\de\\ff".gsub(/\\([a-f][a-f])/o) { | c |            
> irb(main):004:1*    c.to_i(16).chr
> irb(main):005:1> }
> => " \000\000\000"
> 
> これも、おかしい。

c は $& 相当で、つまり「\ab」や「\de」です。
でもって "\\...".to_i は 0 なので、これで正しい結果です。
$1.to_i(16).chr なら予測通りになると思います。
-------------------------------------------------------------------
青木峰郎