这是 Ruby 中一个好的编程实践吗?

  • 本文关键字:编程 一个 Ruby 这是 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 变量提供值?

作为一般规则,属性应在适当时具有默认值,或者应将值传递到构造函数中。在上述情况下,如果您删除了a.m = 4行并运行代码,则会收到此错误:

some.rb:5:in `n': undefined method `+' for nil:NilClass (NoMethodError)
from some.rb:10:in `<main>'

对于对象,如果属性没有默认值,则要求通过构造函数传入它们,如果没有默认值,则失败。这确保了无论对象如何实例化,您都将有一个合理的默认值。传递具有这样公开值的对象是代码中的定时炸弹。

你的代码有两点令人不安:

  1. 您应该通过变量名而不是实例变量名引用attr_accessor设置的值,这意味着这样做

    def n
      m + 1 # and not @m + 1
    end
    
  2. 如果一个变量可以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
    

当属性是可选的或不需要生成对象时,请使用基于 setter 的依赖项注入;当生成对象(或其关键功能)需要属性时,使用基于构造函数的依赖项注入。

在您的情况下,如果类的对象唯一要做的就是调用方法 n然后使用构造函数提供m否则使用setter

相关内容

最新更新