重定義同一個類時,意味著對原有定義進行補充,不會覆蓋原來的定義。而重定義方法時,則會覆蓋原有定義。
6.2 有類變量嗎?從1.6版本開始出現類變量。類變量名前都帶有`@@'。
class Foo @@F = 0 def foo @@F += 1 print @@F, "\n" end end在1.4以前的版本中,使用容器類(Array、Hash等)來代替類變量。
class Foo F = [0] def foo F[0] += 1 print F[0], "\n" end end 6.3 什么是類的實例變量?class Foo @a = 123 # (1) def foo p @a # (2) ... 123でなくnilになる。 end end(1)是類的實例變量、(2)是通常的實例變量。(2)屬于Foo類的實例,而(1)屬于類對象Foo(Class的實例)。
不能在實例方法中直接訪問類的實例變量。
因此上面的實例變量尚未初始化,其值為nil。
6.4 什么是特殊方法?特殊方法是指某實例所特有的方法。
通常這么使用。
foo = Foo.new def foo.hello print "Hello\n" end foo.hello若想向類中添加方法,卻又不想生成子類時,可以使用特殊方法。
Java程序員可能會覺得它很像inner class。
6.5 什么是類方法?類方法就是指類的特殊方法。上面我們提到,特殊方法是歸屬于某對象的方法,那么這里所說的“類的特殊方法”將作何解釋呢?其實Ruby中有一個“元類”的概念。它是Class類的實例,同時又被所有的類所共有。類方法就定義在這個元類中。
從形式上看,將類名當作被調的方法就是類方法。
下面,我們就在Class類的Foo實例中添加一個特殊方法。
class Foo def Foo.test print "this is foo\n" end end像這樣來調用它。
Foo.test您有沒有注意到什么?
對了,這就是所謂的類方法。
當然了,Class中所定義的方法也可以用作類方法。
6.6 什么是特殊類?上面我們提到了特殊方法。
簡單說來,在Ruby中可以向對象(實例)中添加方法。
進一步講,如果您想像操作類那樣來操作對象時,該怎么辦呢?
可千萬別說您沒這么想過(^^;
使用特殊類的話,您就可以做到這一點。
class Foo def hello print "hello.\n" end end foo = Foo.new foo.hello #=> hello. class << foo attr :name, true def hello print "hello. I'm ", @name, ".\n" end end foo.name = "Tom" foo.hello #=> hello. I'm Tom.多棒呀。
好了,現在要問問題了
問題 如果不使用private_class_method的話,能不能將類方法變成private呢?
解答: 類方法就是類的特殊方法。
所以我們可以耍個小花招,這么處理它。
class Foo # ... end class << Foo def class_method print "class method\n" end private :class_method end Foo.class_method #=> Error定義特殊方法時,既可以像上面這樣在特殊類中加以定義,也可以直接使用def obj.method來完成定義。
另外,您還可以在模塊中定義特殊方法(而且是private方法)。
6.7 什么是模塊函數?定義模塊函數時,它們既是模塊的特殊方法,同時又是private類型。例如,您既可以這樣
Math.sqrt(2)來調用它,又可以這樣
include Math sqrt(2)使用include來調用它,的確十分方便。
若您想把某方法定義成模塊函數時,可以在模塊定義中添加如下代碼
module_function :method_name即可完成定義。
6.8 類和模塊有什么區別?模塊不能生成實例,而類不能被include。
6.9 模塊可以生成子類嗎?在類(模塊)中include模塊之后,就可實現類似于多重繼承的Mix-in功能。它與父類子類之間的這種直接繼承關系有所不同,內含模塊的類與該模塊之間存在is_a?的關系。
6.10 在類定義中定義類方法 和 在頂層中定義類方法 之間有什么不同?您在前者中可以直接使用常數,而在后者中則必須指定類名才行。
6.11 load和require有什么不同?load只能加載用Ruby編寫的源文件(*.rb)。
require還可以加載*.o文件。另外,一旦require某文件之后,即使再次require也不會進行加載。
加載路徑也有所不同。
6.12 include和extend有什么不同?include負責將module插入到類(模塊)中,這樣就能以函數的形式來調用方法;而extend負責將module插入到對象(實例)中,這樣就添加了特殊方法。
6.13 self是什么?self是指執行方法的主體本身。在函數形式的方法中,是把self當作被調的。
6.14 MatchData中的begin、end分別返回什么?它們作用于$~,分別返回$0、$1等原來字符串的開始位置和終止位置。請參考展開標簽中的例子。
6.15 如何使用類名來獲得類?如果我有classname = "SomeClass"時,如何生成SomeClass類的實例呢?主要有兩個解決方法。
eval(classname).new Object.const_get(classname).new第1種方法既簡單又可以處理嵌套類(Net::HTTP等),但如果在CGI環境中濫用它的話,將十分危險。
而第2種方法卻又無法處理嵌套類的問題。但如果進行以下處理的話,就可以處理嵌套類了。
# 如果只考慮Ruby 1.8之后的版本的話,可以這樣 c = classname.split(/::/).inject(Object) {|c,name|原文轉自:http://www.anti-gravitydesign.com