How can I implement options hashes? How is the structure of a class that has option hashes in it? Say I have a person class. I want to implement a method such as my_age that when called upon will tell me my age using options hashes.
You could do something like this:
class Person
def initialize(opts = {})
@options = opts
end
def my_age
return @options[:age] if @options.has_key?(:age)
end
end
and now you're able to call to the age like this
p1 = Person.new(:age => 24)<br/>
p2 = Person.new
p1.my_age # => 24<br/>
p2.my_age # => nil
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
Might be worth mentioning that Ruby 2.1 adds the ability to pass in keyword arguments that don't need to be in a particular order AND you can make them be required or have default values.
Ditching the options hash reduces the boilerplate code to extract hash options. Unnecessary boilerplate code increases the opportunity for typos and bugs.
Also with keyword arguments defined in the method signature itself, you can immediately discover the names of the arguments without having to read the body of the method.
Required arguments are followed by a colon while args with defaults are passed in the signature as you'd expect.
For example:
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
In Ruby 2.x you can use **
operator:
class Some
def initialize(**options)
@options = options
end
def it_is?
return @options[:body] if @options.has_key?(:body)
end
end
来源:https://stackoverflow.com/questions/14866910/how-to-implement-options-hashes-in-ruby