如何在Ruby中实现选项哈希?

4

我该如何实现选项哈希?类中具有选项哈希的结构是什么样的?比如我有一个人类(person class),我想要实现一个方法,例如 my_age,当调用它时,使用选项哈希来告诉我我的年龄。


2
我不认为我理解了。你认为“使用选项哈希告诉我我的年龄”和“不使用选项哈希告诉我我的年龄”之间有什么区别?如果使用代码示例(在 `反引号` 中)更容易解释,那就使用它们。 - Gareth
我更新了我的初始问题。我仍然困惑如何实现一个类,可以在创建类的实例时接受选项哈希。 - Andy Huynh
4个回答

6
你可以这样做:

你可以像这样做:

class Person

  def initialize(opts = {})
    @options = opts
  end

  def my_age
    return @options[:age] if @options.has_key?(:age)
  end

end

现在,您可以像这样调用年龄:
p1 = Person.new(:age => 24)<br/>
p2 = Person.new

p1.my_age # => 24<br/>
p2.my_age # => nil

3
class Person
  def birth_date
    Time.parse('1776-07-04')
  end

  def my_age(opts=nil)
    opts = {
      as_of_date: Time.now, 
      birth_date: birth_date,
      unit: :year
    }.merge(opts || {})
    (opts[:as_of_date] - opts[:birth_date]) / 1.send(opts[:unit])
  end
end

1
值得一提的是,Ruby 2.1增加了传递关键字参数的能力,这些参数不需要按特定顺序传递,并且您可以使它们成为必需的或具有默认值。
放弃选项哈希将减少提取哈希选项的样板代码。不必要的样板代码会增加出现拼写错误和错误的机会。
此外,在方法签名中定义关键字参数,您可以立即发现参数的名称,而无需阅读方法体。
必需参数后跟冒号,而具有默认值的参数则像您预期的那样在签名中传递。
例如:
class Person
  attr_accessor(:first_name, :last_name, :date_of_birth)

  def initialize(first_name:, last_name:, date_of_birth: Time.now)   
    self.first_name = first_name
    self.last_name = last_name
    self.date_of_birth = date_of_birth
  end

  def my_age(as_of_date: Time.now, unit: :year)
    (as_of_date - date_of_birth) / 1.send(unit)
  end
end

0
在 Ruby 2.x 中,您可以使用 ** 运算符:
class Some
  def initialize(**options)
    @options = options
  end

  def it_is?
    return @options[:body] if @options.has_key?(:body)
  end
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接