2013-03-07 41 views
0

當我們試圖重新定義一個常量時,Ruby只顯示一個警告,但沒有任何錯誤。所以人們總是可以在Ruby中重新定義一個常量?允許重新定義Ruby常量並允許通過send()方法訪問私有方法的基本原理?

Const = 12 
puts Const 
#only an warning: already initialized constant Const 
Const = 14 
puts Const #Displays 14 
class MyClass 
private 
    def priv 
     puts 'In private method' 
    end 
end 
obj = MyClass.new 
#Error: private method `priv' called for #<MyClass:0x7f2cfda21738> (NoMethodError) 
#obj.priv 
#but this is fine! 
obj.send(:priv) 

是否有紅寶石這樣的設計之後的任何理由:

也是一類的私有方法可以使用send方法被調用?這些不是違反常量和訪問說明符的基本概念嗎?

這些設計是否有任何實際用途?如果有的話,一些例子會很棒!

注意:在這裏我看到很多關於Ruby常量和私有方法的問題/討論,但是我沒有發現任何與這些背後原因相關的問題。

+0

我覺得很簡單。 Ruby不是Java。訪問說明符是指南,而不是規則。 – Linuxios 2013-03-07 14:28:35

+0

@Linuxios忘記Java或任何其他語言,只考慮英文單詞*'constant'*和*'private'*。這些Ruby的設計不要違反這兩個詞的解釋嗎?我已經讀過,Ruby試圖儘可能接近英語口語!事實上,流行的Ruby書籍[爲什麼(對於ruby而言)(指向ruby)](http://mislav.uniqpath.com/poignant-guide/book/)實際上意味着Ruby接近於自己如何思考或閱讀自己的想法介意...... – Curious 2013-03-07 14:37:09

+1

Ruby不會試圖成爲一種執行規則的迂腐語言,例如常量被永久鎖定。如果是這樣,我們應該能夠使用的唯一常數就是我們在科學計算器中發現的那些常數。相反,常量是我們不想改變的東西,但是如果我們意外地做了,Ruby會警告我們,以便我們修復導致警告的代碼。作爲一名程序員,Ruby對我提出異常並停止代碼或者在沒有這樣說的情況下默默地忽略重新分配沒有好處,所以它的當前行爲很好地工作。 – 2013-03-07 15:12:00

回答

3

至於send,答案很簡單:一旦你使用反射,所有的投注都關閉。請注意,這與其他大多數語言也沒什麼不同,例如,您也可以使用反射規避Java中的訪問限制。

而對於常量,那麼你得到一個警告。你被告知你正在做一些你不應該做的事情。但是Ruby是一種相信你的語言,你知道你在做什麼。它不會妨礙你。如果你想在腳下自己射擊,你應該被允許這樣做。或者,更加憤世嫉俗的方式來看待它:在Ruby中可以做很多邪惡的事情,重新定義常量確實無關緊要。