Ruby之類的真相

[b]打開類和猴子補丁[/b]
在Ruby中,類定義的方法和其他的語句沒有任何區別,都是一行一行的執行下去的。如下例子:
class Example
def method_1
puts "method 1"
end
end
class Example
def method_2
puts "method 2"
end
end

本例中,當第一次定義Class Example的時候,還沒有一個叫做Example的Class存在,因此,Ruby開始定義這個類,當後面在定義這個類時,Ruby會發現該類已存在,並返回這個類,而不是定義一個新類。

因爲這個特性,因此,Ruby天生具有打開一個已經存在的類,並動態修改其內容的能力,即使其是標準類庫的類也不例外。比方說,可以給SDK的String類添加一個去除String中的標點符號和特殊字符的方法:to_alphanumeric
class String
def to_alphanumeric
gsub /[^\w\s]/, ''
end
end
“H&&^^ello”.to_alphanumeric #==>Hello

,然後,所有的String對象都具備“to_alphanumeric”的能力了,這種技術一般簡稱爲打開類技術。

上面描述的打開類技術其實是隱含了一定的風險的,尤其是在大型系統中使用打開類技術擴展標準類庫時,因爲,很多開發人員都在擴展類,當多個擴展方法的名字一樣時, 後定義的總會覆蓋掉前面,從而導致整個系統的崩潰,業界把這種魯莽的修改類的方式簡稱爲猴子補丁(Monkey Patch)。因此在使用打開類技術時,一定要慎之又慎。

[b]類的真相[/b]
實例變量
在Ruby中,實例變量是存儲在對象中,但是,其於該對象的類沒有關係,當給對象的實例變量賦值時,該實例變量就生成了,說白了,實例變量就像是一個掛載在對象上的HashMap,每個對象都可以用自己不同的HashMap, 如下例:

class Person
def name
@name = "xianlinbox"
end
end
p = Person.new
puts p.instance_variables #==>nil
p.name
puts p.instance_variables #==>@name


方法
作爲一個對象,除了有實例變量(也可以稱之爲屬性),還需要有方法。 但是在Ruby中,關於方法的定義並不在對象中,而是在對象自身的類中,這是因爲“共享同一個類的對象也必須共享同樣的方法”。但是,不能說Class有一個叫做“method”的方法,因爲無法使用"Class.method"調用該方法,而要說Class有一個實例方法“method”,這意味着必須創建該類的實例對象,通過實例對象調用該方法。

如果要定義類方法,那麼在定義方法的時候,必須加類名前綴,如下:
class Person
def Person.name
@name = "xianlinbox"
end
end


類本身也是對象
在Ruby中Class本身也是一個對象,關於對象的所有規則都適用於Class.
puts "hello".class                   #=> String
puts String.class #=> Class
puts Class.class #=> Class
puts Class.instance_methods(false) #=> [:superclass,:allocate,:new]
puts Class.instance_variables #=> nil


類的繼承體系
puts String.superclass        #=> Object  
puts Class.superclass #=> Module
puts Module.superclass #=> Object
puts Object.superclass #=> BasicObjec
puts BasicObject.superclass #=> nil

[list]
[*]BasicObject是繼承體系的根節點。
[*]所有類都繼承自Object。
[*]Class是對Module的繼承增強,增加了new()和allocate()方法以創建實例。
[/list]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章