class A
attr_accessor :m
def n
@m + 1
end
end
a = A.new
a.m = 4
p a.n
我在讨论“n”方法中你有@m + 1的代码。这种代码是否容易崩溃,因为我没有要求用户为@m变量赋值? / p>
答案 0 :(得分:1)
作为一般规则,属性在适当时应具有默认值,或者值应传递到构造函数中。在上述情况下,如果您删除a.m = 4
行并运行代码,则会出现此错误:
some.rb:5:in `n': undefined method `+' for nil:NilClass (NoMethodError)
from some.rb:10:in `<main>'
对于对象,如果属性不具有默认值,则要求它们通过构造函数传入,如果不是,则失败。这确保了无论对象如何实例化,您都将拥有一个理智的默认值。绕过一个具有暴露值的物体,就像代码中的定时炸弹一样。
答案 1 :(得分:0)
您的代码有两点令人不安:
您应该使用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
答案 2 :(得分:0)
当属性是可选的或不需要构建对象时,使用基于setter的依赖注入,当构建对象(或其关键功能)需要属性时,使用基于构造函数的依赖注入。
在你的情况下,如果你的类中唯一的对象是调用方法n
,那么使用构造函数来提供m
否则使用setter