Reputation: 838
I have an initialize
method that accepts a hash to set some instance variables. This is basically what I'm trying to do:
class Ad
DEFAULT_PAGE = 'index'.freeze
DEFAULT_CHANNEL = 'general'.freeze
DEFAULT_AREA = 'general'.freeze
attr_accessor :page, :area, :channel
def initialize args={}
@page = args[:page] || DEFAULT_PAGE
@area = args[:area] || DEFAULT_AREA
@channel = args[:channel] || DEFAULT_CHANNEL
end
# ...
end
I saw a tip to allow dynamic setting of instance variables, but I'm not sure how to also include the default values...
def initialize args={}
args.each do |attr,val|
instance_variable_set("@#{attr}", val) unless val.nil?
end
end
Can I refer to a constant dynamically? Or any better ways of doing this sort of thing are welcome!
... I also realize that attr_accessor
variables can be set individually. But I just want to do it like this. :)
Upvotes: 3
Views: 6488
Reputation: 64363
Try this:
def initialize args={}
defaults = {
:page => DEFAULT_AREA,
:area => DEFAULT_AREA,
:channel => DEFAULT_CHANNEL
}
args.reverse_merge(defaults).each do |attr,val|
instance_variable_set("@#{attr}", val) unless val.nil?
end
end
Upvotes: 1
Reputation: 38606
This one also only creates the instance variables if they are in your defaults
hash, so that you don't accidentally create/overwrite other instance variables.
I'm assuming you meant to say unless val.nil?
:
def initialize(args={})
defaults = {
:page => DEFAULT_PAGE,
:area => DEFAULT_AREA,
:channel => DEFAULT_CHANNEL
}.merge(args).each do |attr, val|
instance_variable_set("@#{attr}", val) if defaults.has_key?(attr) && (not val.nil?)
end if args
end
Upvotes: 10