當你調用類方法時,你可以修改一個類嗎?還是隻是爲了設置屬性,就像這個例子。Ruby中類方法的其他用法是什麼,除了設置類的屬性/變量之外?
class UnitedStatesPresident
def self.citizenship
"United States of America"
end
end
p UnitedStatesPresident.citizenship
當你調用類方法時,你可以修改一個類嗎?還是隻是爲了設置屬性,就像這個例子。Ruby中類方法的其他用法是什麼,除了設置類的屬性/變量之外?
class UnitedStatesPresident
def self.citizenship
"United States of America"
end
end
p UnitedStatesPresident.citizenship
您可以使用一個類的方法修改的類。下面是定義了新的方法,其目的是將方法添加到類(本身)類已經被定義之後的示例:
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消息,該消息是私有的。作者不情願地這樣做,將這種風格稱爲「黑客」。
是的,你可以使用「類方法」修改一個類。 (請注意,實際上,沒有類方法這樣的事情,類方法就像其他單例方法一樣是單例方法,實際上,單例方法也不存在,它們只是單例類的常規實例方法。或者,他們是類的類,這是Class
或其任何超類(Module
,Object
,BasicObject
)的只是實例方法。)
其實,我很奇怪,你有沒有遇到一些類來已經修改類的方法!下面是一些例子:
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
,private
或attr_*
呢。
很棒的回答。所以一個類方法本質上是超類的一個實例方法,當調用'Foo.bar'時你實例化Foo的超類? – Mohamad 2014-09-04 12:38:59
不,類方法是類的實例方法,就像任何其他對象一樣。如果調用'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
沒有實例化(除非你調用'new'或'allocate'),這與超類無關。 – 2014-09-05 06:37:07
你想如何修改一個類?添加一個新的方法或修改被調用的方法? – pangpang 2014-09-03 03:11:30