From: "David A. Black" Date: 2009-10-27T00:45:22+09:00 Subject: Re: Setting instance variables from hash parameters (with defaults) Hi -- On Tue, 27 Oct 2009, Leslie Viljoen wrote: > Hi! > > I'm sure I might be reinventing the wheel here. > I was writing the following ugly code in order to set options (with > defaults) from a hash: > > def initialize(opts = {}) > @select_max = opts.has_key?(:select_max) ? opts[:select_max] : 10000 > @select_try = opts.has_key?(:select_try) ? opts[:select_try] : 1000 > @min_sleep_sec = opts.has_key?(:min_sleep_sec) ? opts[:min_sleep_sec] : 5 > @max_sleep_sec = opts.has_key?(:max_sleep_sec) ? opts[:max_sleep_sec] : 1800 > @default_sleep = opts.has_key?(:default_sleep) ? opts[:default_sleep] : 10 > .... > > So to avoid that I wrote: > > module Defaulting > def set_params(defs, params) > defs.each do |name, val| > if params.has_key?(name) > eval "@#{name} = params[name]" > else > eval "@#{name} = val" > end > end > end > end > > So that I could do the much nicer: > > include Defaulting > def initialize(opts = {}) > defs = { > :select_max => 10000, > :select_try => 1000, > :min_sleep_sec => 5, > :max_sleep_sec => 1800, > :default_sleep => 10 > } > set_params(defs, opts) > > .... > > Note that this allows me to pass options that are explicitly set to nil. > > Now: > 1. Is this functionality already tucked away somewhere else? > 2. How can I get rid of those nasty evals? Starting with #2: you can always do: instance_variable_set("@#{name}", value) For the initialize thing, I would probably do something like this: class Whatever DEFAULTS = { :select_max => 10000, :select_try => 1000, :min_sleep_sec => 5, :max_sleep_sec => 1800, :default_sleep => 10 } def initialize(opts) DEFAULTS.update(opts).each do |name, value| instance_variable_set("@#{name}", value) end end end Another thing to keep in mind for similar cases is that hashes return nil (unless you override the default) for non-existent keys. So, unless you have a hash where nil might be a valid value, you can do: h[x] ||= y rather than checking for a key. David -- The Ruby training with D. Black, G. Brown, J.McAnally Compleat Jan 22-23, 2010, Tampa, FL Rubyist http://www.thecompleatrubyist.com David A. Black/Ruby Power and Light, LLC (http://www.rubypal.com)