2013-09-27 88 views
4

define_methodModule的一種方法。Ruby 2.0 define_method in main

在Ruby 2.0中,define_method可以用在頂層;它不必在類或模塊內部。

define_method :kick do 
    puts "method" 
end 

在Ruby 1.9中,main對象不具有該方法define_method

define_method :kick 
# => NoMethodError: undefined method `define_method' for main:Object 

Ruby 2.0如何實現這個?

+0

我應該使用更好的示例。其實我只是想問一下'define_method'。 – txworking

+0

你爲什麼要在'main'上下文中定義一些東西? – tadman

+0

@txworking你只是好奇,還是有你想解決的實際問題? – Stefan

回答

2

我也很好奇這個功能,並使用irb嘗試一點。請看看:

% irb 
2.0.0-p353 :001 > method(:define_method) 
=> #<Method: main.define_method> 
2.0.0-p353 :002 > private_methods(false) 
=> [:public, :private, :include, :using, :define_method, :irb_exit_org, :default_src_encoding, :irb_binding] 
2.0.0-p353 :003 > singleton_class.private_instance_methods(false) 
=> [:public, :private, :include, :using, :define_method, :irb_exit_org] 

它表明define_method是主對象(頂層self)的私有單例方法。在uncutstone的偵探

+0

也許在輸出'=> main'時用'2.0.0-p481:001> self'開始你的irb輸出可能會讓事情變得更清晰 - 因爲在ruby中,當你沒有明確指定接收者時,ruby會使用self,所以在你的代碼中main是對象調用方法(),private_methods()和singleton_class()。無論如何。 – 7stud

0

大廈define_method()不是由主要的單類繼承:

class <<self 
    p private_instance_methods(false) 
end 

--output:-- 
[:public, :private, :include, :using, :define_method] 

...而據我判斷,如果是不能繼承的方法,它必須被定義在課堂裏。需要注意的是,當你有一個模塊,紅寶石創建一個匿名類,並插入模塊的DEFS在匿名類,然後直接插入匿名類的方法查找鏈中包括類以上,例如:

module A 
    def greet 
    puts 'hi' 
    end 
end 

class Dog 
    include A 
end 

p Dog.instance_methods(false) 
p Dog.instance_methods.grep(/^g/) 

--output:-- 
[] 
[:greet] 

的輸出顯示,greet()是一種繼承的方法。但是因爲define_method()沒有被main的singleton類繼承,所以define_method()不能通過包含模塊來獲得。相反,似乎define_method()必須在main的singleton類中定義。所以實現的一種方法是讓Ruby解釋器在解析代碼之前執行以下代碼:

class <<self 
    def define_method(x, *y) 
    #same code as in Module's define method 
    end 
end