Ruby 位置参数和选项哈希哪个更惯用?

Ruby 位置参数和选项哈希哪个更惯用?,ruby,methods,variable-assignment,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 initi

我是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
散列传递:

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
哪一种方法最为惯用,或者有没有我在这里没有介绍的替代方法?

第一种方法(直接赋值)更为惯用,除非您传递的选项列表可能会用到,也可能不会用到

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

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

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

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

但这里有一种方法我非常喜欢,因为它非常灵活和可进化:

def initialize(options = {})
  @id = options.fetch(:id, SOME DEFAULT VALUE)
  etc...
end
方法签名的多样性 您所谓的“直接赋值”实际上只是一个带有位置参数的方法签名。从散列参数赋值是您在遗留代码中经常看到的,因为版本2.0之前的Ruby解释器没有,而选项散列是模拟它们的好方法

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

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

是的,为了简单起见,我省略了默认参数。当然,这是一个品味问题,但我通常使用选项。fetch(:id,)就是这样,我习惯了它,因为它可以干净地处理需要在参数哈希中允许布尔值的情况。另一个选项是ruby 2.0关键字参数