トップ «前の日記(2006-12-02) 最新 次の日記(2006-12-06)» 編集

Route 477



2006-12-04

[ruby] define_methodで変なメソッド名が作れるんだが

Hpricotのソースを見てたら 意味不明な記述に遭遇。

 module Container::Trav
   def self.filter(tok, &blk)
     define_method("filter[#{tok.is_a?(String) ? tok : tok.inspect}]", &blk)
   end
   中略
   filter '@^=' do |attr,val,i|
      get_attribute(attr).to_s.index(val) == 0
   end

メソッド名が filter[@^=] とか、ありえないですよね。

irb(main):011:0> class Object; define_method("filter[@^=]"){ "asdffdsa" }; end
=> #<Proc:0x00002aaaabb5db68@(irb):11>

irb(main):017:0> 1.methods.find{|m| m=~/filter/}
=> "filter[@^=]"

と思いきや、普通に定義できたwww

irb(main):013:0> 1.filter[@^=]
SyntaxError: compile error
(irb):13: syntax error
1.filter[@^=]
         ^
       from (irb):13

呼び出しはもちろんsyntax error。

irb(main):014:0> 1.__send__("filter[@^=]")
=> "asdffdsa"
irb(main):015:0>

と思いきや、__send__使えば呼べるらしい。

define_methodで普通許されない名前のメソッドが定義できるのって仕様なんですかね?