!が着いたメソッド探し

ObjectSpaceを使って、!が着いたメソッド探しをしましょう!(←これは感嘆符)

name = Array.new

ObjectSpace.each_object(Class) do |c|
  c.instance_methods(false).each do |mname| # super not included
    if /\!$/ =~ mname
      name << "i #{c.to_s}##{mname}"
    end
  end
  c.singleton_methods.each do |mname|
    if /\!$/ =~ mname
      name << "c #{c.to_s}.#{mname}"
    end
  end
end

name.sort.each do |s|
  puts s
end

実行結果です。意外と少ないですね。頭にcが付いているのは特異メソッド(クラスの場合にはクラスメソッド)です。

c Gem::SourceIndex.terminate_interaction!
c NameError::message.!
c Rational.new!
i Array#collect!
i Array#compact!
i Array#flatten!
i Array#map!
i Array#reject!
i Array#reverse!
i Array#slice!
i Array#sort!
i Array#uniq!
i Bignum#power!
i Fixnum#power!
i Gem::SourceIndex#refresh!
i Gem::StreamUI#terminate_interaction!
i Hash#merge!
i Hash#reject!
i OpenSSL::BN#clear_bit!
i OpenSSL::BN#mask_bits!
i OpenSSL::BN#set_bit!
i OpenSSL::PKey::DH#generate_key!
i String#capitalize!
i String#chomp!
i String#chop!
i String#delete!
i String#downcase!
i String#gsub!
i String#lstrip!
i String#next!
i String#reverse!
i String#rstrip!
i String#slice!
i String#squeeze!
i String#strip!
i String#sub!
i String#succ!
i String#swapcase!
i String#tr!
i String#tr_s!
i String#upcase!

疑問:上記に出てくるNameError::message.!って何でしょうね。riやrefeでは見つけられませんでした。
追記:(最近何かと関わりの多い)ささださんからコメントで、「Class→Module」と「grep ! error.c」と「puts name.sort」というヒントをいただきました。

C:\ruby\src\ruby-1.8.4>grep \"!\" error.c
error.c:    rb_define_singleton_method(rb_cNameErrorMesg, "!", name_err_mesg_new, 3);

ふうむ…。
ま、とりあえず、ささださんからのコメント反映したスクリプトです。

name = Array.new

ObjectSpace.each_object(Module) do |c|
  c.instance_methods(false).each do |mname| # super not included
    if /\!$/ =~ mname
      name << "i #{c.to_s}##{mname}"
    end
  end
  c.singleton_methods.each do |mname|
    if /\!$/ =~ mname
      name << "c #{c.to_s}.#{mname}"
    end
  end
end

puts name.sort

追記:id:sumimさんから、ループ中でifでチェックするのではなく、grepを噛ませる方法を教えていただきました。感謝♪

name = Array.new

ObjectSpace.each_object(Module) do |c|
  c.instance_methods(false).grep(/\!$/) do |mname| # super not included
    name << "i #{c.to_s}##{mname}"
  end
  c.singleton_methods.grep(/\!$/) do |mname|
    name << "c #{c.to_s}.#{mname}"
  end
end

puts name.sort

追記:なかださんから「NameError::message.!はNameErrorのmarshalのために内部的に使うもの」という情報をいただきました。感謝です♪