2011-03-22 67 views
2

我是Ruby的首發。我發現這兩者都非常相似(在輸出中),但我無法理解下面上下文中的差異。例如,我有一個類class_eval和class << className有什麼區別?

class Say 
    def self.hello 
    puts "hello" 
    end 
end 

,並可以擴展這樣

class << Say 
    def hi 
    puts "hi" 
    end 
end 

,也喜歡這個

Say.class_eval do 
    def self.bye 
    puts "bye" 
    end 
end 

我什麼時候應該使用<<class_eval

回答

13

class_eval實際上與class << className沒有任何關係。

A.class_eval do 
    ... 
end 

相當於

class A 
    ... 
end 

有一些不同。 class_eval使用一個塊(或一個字符串,但暫時忽略它),這意味着它關閉了包含的詞法範圍。換句話說,你可以使用周圍範圍的局部變量。常見的課程塊引入了一個全新的範圍。同樣,您可以創建塊並將其傳遞給許多不同的class_eval,塊的主體將在您調用class_eval的類的上下文中執行。

class << className打開單個類className,允許您定義類方法。

class << A 
    def foo 
    ... 
    end 
end 

相同

def A.foo 
    ... 
end 

注意,他們是奧菱類的方法,如果A恰好是一個類(幾乎)在Ruby中的所有對象都具有單班,你可以使用定義它們的方法這兩種語法中的任何一種。 class << obj的優點主要在於您一次定義多個單例方法。

1

前面已經說過class_eval有真的不多做

class <<self 

即使他們似乎做同樣的事情在你的例子(儘管效果類似於它沒有這樣做,也有細微的差異)。

下面是另一個例子,其中所述第二形式的使用是更更清楚:

class A 

end 


a = A.new 
b = A.new 

class <<b 
    def say_hi 
    puts "Hi !" 
    end 
end 


b.say_hi # will print "Hi !" 
a.say_hi # will raise an undefined method 

a和b是相同的類A的兩個對象,但我們添加的方法b的元類,因此方法say_hi僅適用於b對象。

相關問題