2014-09-03 25 views

回答

2

可以使用一個類的方法修改的類。下面是定義了新的方法,其目的是將方法添加到類(本身)類已經被定義之後的示例:

class UnitedStatesPresident 
    def self.citizenship 
     "United States of America" # Notice the absence of backticks (`) 
    end 

    def self.create_method(name, &block) 
     self.class.send(:define_method, name, &block) 
    end 
end 

p UnitedStatesPresident.citizenship # => "United States of America" 

UnitedStatesPresident.create_method(:name) do 
    "Barack Obama" 
end 

p UnitedStatesPresident.name # => "Barack Obama" 

欲瞭解更多信息,請參閱文檔:http://www.ruby-doc.org/core-2.1.2/Module.html#method-i-define_method

編輯:請注意,文檔的作者在上面的示例中使用#send來發送#define_method消息,該消息是私有的。作者不情願地這樣做,將這種風格稱爲「黑客」。

1

是的,你可以使用「類方法」修改一個類。 (請注意,實際上,沒有類方法這樣的事情,類方法就像其他單例方法一樣是單例方法,實際上,單例方法也不存在,它們只是單例類的常規實例方法。或者,他們是類的類,這是Class或其任何超類(ModuleObjectBasicObject)的只是實例方法。)

其實,我很奇怪,你有沒有遇到一些類來已經修改類的方法!下面是一些例子:

  • Module#private不帶參數:設置後它定義方法的默認能見度private
  • Module#protected不帶參數:設置後它定義方法的默認能見度protected
  • Module#public沒有參數:將其後定義的方法的默認可見性設置爲public
  • Module#attr_reader生成吸氣方法
  • Module#attr_writer生成setter方法
  • Module#attr_accessor產生的吸氣劑/ setter方法對
  • Module#include混合了模塊插入繼承鏈作爲超
  • Module#prepend混合了模塊插入繼承鏈正下方
  • Module#alias_method創建一個方法副本
  • Module#const_set設置常數
  • Module#remove_const刪除常數
  • Module#class_variable_set集的類變量
  • Module#remove_class_variable移除類變量
  • Module#define_method限定的方法
  • Module#undef_method取消定義的方法
  • Module#remove_method去除的方法
  • Module#refine創建一個細化
  • Module#using激活細化

我很驚訝你還沒有遇到alias_method,privateattr_*呢。

+0

很棒的回答。所以一個類方法本質上是超類的一個實例方法,當調用'Foo.bar'時你實例化Foo的超類? – Mohamad 2014-09-04 12:38:59

+0

不,類方法是類的實例方法,就像任何其他對象一樣。如果調用'some_array.foo',該方法在'some_array'類中查找,它是'Array'。如果你調用'some_string.foo',這個方法將在'some_string'的類中查找,它是String。如果你調用'SomeClass.foo',這個方法將在'SomeClass'類中查找,它是Class。或者,或者Ruby也有* singleton class *的概念;每個對象都有其唯一的單例類,它是唯一的實例。方法也可以在那裏定義。 – 2014-09-05 06:36:25

+0

沒有實例化(除非你調用'new'或'allocate'),這與超類無關。 – 2014-09-05 06:37:07

相關問題