Ruby 1.9のSymbolがStringっぽい理由

Ruby 1.9に移行する際に注意すべき10のポイント - なんとなく日記

==== Symbol が String のように

Symbol が String のようになる.正規表現や upcase/swapcase,その size を得ることができ る.この目的が何なのかわからない.完全に String のようになるのでなければ,これ以上 Symbol を String のようにしたくない.


「これ以上SymbolをStringのようにしたくない」という気持ちはわかるのだが、致し方ないとしか言いようがない。俺も最初はキモいと思ったのだが…

なぜなら、以下の変更のため。

==== メソッド名は Symbol で返る

1.9 では obj.method や klass.instance_methods が,String ではなく Symbol を返すように なる.もし String で欲しいなら,to_s しなければならない.でもねぇ....

Ruby 1.9ではメソッド名に限らず、ありとあらゆる「名前」がSymbolで返されるようになる。しかし、SymbolがStringっぽくなければ以下のコードは動かなくなる。動的にメソッド名を得たりとかはRubyでは比較的定番となっている。キモいだろうけど互換性のためにはやむをえないのだと思うよ。

# -*- coding: euc-jp -*-
class C
  def do_print() end
  def do_browse() end
  def hoge() end
end

c = C.new
methods = c.methods - Object.instance_methods # => [:do_print, :do_browse, :hoge]
# do_から始まるメソッド名を得る
methods.select {|m| m =~ /^do_/ } # => [:do_print, :do_browse]
# 長さが5以上のメソッド名を得る
methods.select {|m| m.length >= 5 } # => [:do_print, :do_browse]

特定のメソッド名のメソッドを立て続けに実行するとか、そういう処理書いた人けっこういるんじゃないの?Emacs Lispでいう run-hook-with-args、 run-hook-with-args-until-failure、 run-hook-with-args-until-success みたいな処理。メソッドを追加するだけでさくっと挙動をカスタマイズできるのは嬉しいものだ。

っつーか、わざわざStringで返す必要なんてないと思うのだが?式展開とかで勝手に文字列化されるし。

原文のコメント欄が閉じてあるからつっこめない(^^;

追記[2009/01/27]

id:ujihisaさんども。Enumerable#grepが短くていいですね。