我是一名經驗豐富的Obj-C/Java程序員,正在進入Ruby。很顯然,它的動態性非常好(重新開放的類很棒!),但是當我開始編寫Ruby代碼時,有一件事讓我感到擔憂。在Ruby中明確設置iVar類(ala Obj-C)
我很想知道你的Ruby-ERS做(如果有的話)明確設置實例變量的類型,在你自己的類。從我所看到的,你可以設置一個iVar任何對象,紅寶石不會抱怨。但是,如果您希望特定的iVar屬於某種類型,那麼它可能會導致問題。例如:
class MyString
def initialize(myString)
@myString = myString
end
def uppercase_my_string
@myString.upcase
end
end
st1 = MyString.new("a string!")
st1.uppercase_my_string
st2 = MyString.new(["a string"])
st2.uppercase_my_string
該代碼將拋出NoMethodError
,由於當然陣列沒有方法upcase
。遺憾的是它並沒有告訴我們,我們真的出了問題(上面的線,創造str2
時),所以在調試時我們沒有幫助很大(如果str2
發生在一些不顯眼的地方創建幾個模塊遠) 一個很自然的一步可能是添加一些檢查initialize
如下:
class MyString
def initialize(myString)
raise TypeError, "myString iVar is not a string!" unless myString.class == String
@myString = myString
end
end
...same code as before
太好了,現在如果我們不小心創建一個新的MyString我們被告知我們如何傻了(更重要的是,當我們做到這一點,我們被告知,而不是當我們我的下一個問題是當我們決定在iVar上使用attr_accessors
時。
class MyString
attr_accessor :my_string
def initialize(my_string)
raise TypeError, "myString iVar is not a string!" unless my_string.class == String
@my_string = my_string
end
def uppercase_my_string
@my_string.upcase
end
end
st1 = MyString.new("a string!")
st1.uppercase_my_string
st2 = MyString.new("good, it's a string")
st2.my_string = ["an array!"]
st2.uppercase_my_string
使用規定的制定者,我們可真卑鄙,避開錯誤的initialize
檢查。再次有這個問題拋出異常uppercase_my_string
而不是當我們不小心設置@my_string
到一個數組。
最後,我們可以手動創建的存取,並添加錯誤檢查,但是這是一個巨大的痛苦...有一個更快,更簡單的方式來做到這一點。 或者我只是想關閉頭腦,不夠動態?
謝謝!
題外話:我知道,在對象 - 你仍然在運行同樣的問題,但通常你會發現編譯器錯誤說你要指定array
類型的對象,以string
類型的變量(或類似的東西),所以至少我們警告它發生在哪裏
「你不用擔心Ruby中的類型太多,你擔心什麼方法響應」 - 什麼方法響應*是它的類型。 –
謝謝,我儘量多的,但只是想知道是否有辦法 - 似乎沒有,但最有可能的是,因爲它不是紅寶石般的 - 這樣做。 'is_?'方法的好處,我將在未來使用它來檢查類/類的成員。 – Patrick
Ruby中有很多DWIM(和大多數情況一樣,好的和不好的:)一般來說,儘管使用更窄的'respond_to?'來支持'is_a?';當然,在現實世界中,你必須切合實際並做任何事情。 –