class A
attr_accessor :m
def n
@m + 1
end
end
a = A.new
a.m = 4
p a.n
我在談論「n」方法中你有@m + 1的代碼。這種代碼易於崩潰,因爲我沒有要求用戶給@m變量賦值?這是一個很好的Ruby編程習慣嗎?
class A
attr_accessor :m
def n
@m + 1
end
end
a = A.new
a.m = 4
p a.n
我在談論「n」方法中你有@m + 1的代碼。這種代碼易於崩潰,因爲我沒有要求用戶給@m變量賦值?這是一個很好的Ruby編程習慣嗎?
作爲一般規則,屬性在適當的時候應該有默認值,或者值應該傳遞給構造函數。在上述情況下,如果你刪除的a.m = 4
線並運行代碼,你會得到這樣的錯誤:
some.rb:5:in `n': undefined method `+' for nil:NilClass (NoMethodError)
from some.rb:10:in `<main>'
對於對象,如果屬性不有一個默認值,要求他們傳遞通過構造函數進入,如果沒有則失敗。這可以確保無論對象如何實例化,您都將擁有一個合理的默認值。傳遞一個具有暴露值的對象就是代碼中的一個定時炸彈。
除了有一個默認值,另一個選項是引發一個帶有解釋性錯誤信息的異常。 – tokland
有兩件事情稍微打擾你的代碼:
你應該把自己的變量名,而不是他們的實例變量名引用與attr_accessor
設定值,這意味着這樣做
def n
m + 1 # and not @m + 1
end
如果一個變量可以是nil
,您應該以某種方式防範涉及它的所有涉及nil
的操作,即使這意味着引發自定義錯誤,因爲「未定義的NilClass方法+」不是真實的描述性錯誤。這意味着寫這樣的東西會更好
def n
raise StandardError.new("m is not set in instance of A") if m.nil?
m + 1
end
如果您要尋找錯誤,這將節省您的時間。此外,您還可以使用默認值m
,如果你有一個,而是將其放置在初始化則:
def initialize
super()
self.m = 3 #or
# self.m ||= 3 This would only set m if it wasn't set by initialization in a superclass
end
使用二傳手基於依賴注入時的屬性是可選的或不需要的建設的對象,當構建對象(或其關鍵功能)需要該屬性時,使用基於構造函數的依賴注入。
在你的情況,如果你的類會做的唯一的事情就是對象調用方法n
然後使用構造提供m
也可以使用一個二傳手
爲什麼你就不能定義一個初始化方法和設置的值@m爲0以避免崩潰的風險? – davidrac
如果我刪除m,它會起作用。但是,如果我做m = m + 1,程序就會崩潰。但是,self.m = m + 1的作品。 :O – daremkd