哪个更惯用:位置参数或选项哈希?

时间:2013-06-20 03:49:05

标签: ruby methods variable-assignment

我是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

哪个是最惯用的,还是有另外一种我没有涉及的方式?

3 个答案:

答案 0 :(得分:4)

方法签名的Arity

你所谓的“直接分配”实际上只是一个带位置参数的方法签名。散列参数的赋值是你在遗留代码中看到的很多东西,因为2.0之前的Ruby解释器没有keyword arguments,而选项散列是模拟它们的好方法。

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

使用明确签名进行清晰度

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

答案 1 :(得分:1)

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

另一种方法是从Struct

的实例继承
class Foo < Struct.new(:id, :name)
end

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

答案 2 :(得分:1)

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

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

def initialize(options = {})
  @id = options.fetch(:id, SOME DEFAULT VALUE)
  etc...
end