This is a common way to set a default in Ruby:
class QuietByDefault
def initialize(opts = {})
@verbose = opts[:verbose]
end
end
This is an easy trap to fall into:
class VerboseNoMatterWhat
def initialize(opts = {})
@verbose = opts[:verbose] || true
end
end
This is a correct way to do it:
class VerboseByDefault
def initialize(opts = {})
@verbose = opts.include?(:verbose) ? opts[:verbose] : true
end
end
What is the best / cleanest way to code VerboseByDefault
? (I could factor it out, of course.)
What pattern is widely used, if any, in Ruby code in general? Does ActiveSupport have a pattern for this? (Minimal is better -- I don't need a full command line option parser.)
Ranting P.S.: I don't like the asymmetry between code that handles a default true
vs. code that handles a default false
option. A pattern that makes changing between the two -- without causing bugs -- would be a good thing to see.
A simple way to do it is by using the second argument to Hash#fetch
class VerboseByDefault
def initialize(opts = {})
@verbose = opts.fetch(:verbose, true)
end
end
For complex defaults, fetch can also take a block, which is executed if the value isn't in the hash. See: http://ruby-doc.org/core-1.9.3/Hash.html#method-i-fetch
I've commonly seen it as setting all your defaults, and then merging them with the opts. such as..
def initialize(opts = {})
@options = { :verbose => false, :foo => 42 }
@options.merge!(opts)
# ...
end
This way all of your options are set in one place and you just merge the user supplied ones.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With