2

我是 Ruby 的新手,我已经看到构造函数做了几种不同的方式,我很好奇哪种方式更惯用?这是我见过的两种最常见的变体:

直接赋值:

class Foo

  attr_accessor :id
  attr_accessor :name

  def initialize(id, name)
    @id = id
    @name = name
  end

end

哈希传递:

class Foo

  attr_accessor :id
  attr_accessor :name

  def initialize(options)
    @id = options[:id]
    @name = options[:name]
  end

end

哪个是最惯用的,或者有没有我在这里没有介绍的替代方法?

4

3 回答 3

4

方法签名的数量

您所说的“直接分配”实际上只是带有位置参数的方法签名。散列参数的赋值在遗留代码中很常见,因为 2.0 版之前的 Ruby 解释器没有关键字参数,而选项散列是模拟它们的好方法。

两者都不是更惯用的。每个都有不同的用例。通常,当您想要强制方法的 arity 时,位置参数会更好,而当您想要避免复杂的、依赖于顺序的签名并愿意自己处理 nil 和 arity 问题时,选项哈希会更好。

使用显式签名以获得清晰性

如果您使用的是 Ruby 2.0 或更高版本,我建议您坚持使用位置或关键字参数来明确您的方法签名。作为额外的好处,具有良好变量名称的显式签名减少了您需要编写的文档数量;像RDoc这样的工具可以很好地记录表达性签名,但选项哈希很少是不言自明的。

于 2013-06-20T04:37:57.167 回答
1

第一种方式(直接赋值)更惯用,除非您传递一个可能会或可能不会使用的选项列表。

另一种方法是从 的实例继承Struct

class Foo < Struct.new(:id, :name)
end

这不是惯用的,但我喜欢它,因为它传达了红宝石的力量。

于 2013-06-20T04:09:15.733 回答
1

根据我的经验,两者都不比另一个更惯用。

但这是我非常喜欢的一种方法,因为它非常灵活且可进化:

def initialize(options = {})
  @id = options.fetch(:id, SOME DEFAULT VALUE)
  etc...
end
于 2013-06-20T04:11:20.850 回答