patternrubyMajor
Setting defaults in a Ruby options hash
Viewed 0 times
defaultsoptionshashsettingruby
Problem
I have a specific method that I like because it lets me decide whether or not I want to use the default. If I want anything different I enter in
How can I accomplish the same thing in a more elegant manner?
:option => value otherwise I get the default. Here's a concrete example that works, but is a little ugly.How can I accomplish the same thing in a more elegant manner?
def connect_to_oracle opts = {}
host_name = opts[:host_name]
host_name ||= 'a_default_host_name'
db_name = opts[:db_name]
db_name ||= 'a_default_db_name'
userid = opts[:userid]
userid ||= 'a_default_userid'
password = opts[:password]
password ||= 'a_default_password'
url = "jdbc:oracle:thin:#{userid}/#{password}@#{host_name}:1521:#{db_name}"
$db = Sequel.connect(url)
endSolution
You don't need the
Another approach is
or:
I prefer the version with
Another advantage: I can easily add checks if my interface contains correct keys.
Example:
My method call contains an error (forgotten 'e'), but when you call it, you get a warning
||= you can use ||:def connect_to_oracle( opts = {} )
host_name = opts[:host_name] ||'a_default_host_name'
db_name = opts[:db_name] || 'a_default_db_name'
userid = opts[:userid] || 'a_default_userid'
password = opts[:password] ||'a_default_password'
url = "jdbc:oracle:thin:#{userid}/#{password}@#{host_name}:1521:#{db_name}"
$db = Sequel.connect(url)
endAnother approach is
Hash.merge:DEFAULT = {
host_name: 'a_default_host_name',
db_name: 'a_default_db_name',
userid: 'a_default_userid',
password: 'a_default_password',
}
def connect_to_oracle( opts = {} )
opts = DEFAULT.merge(opts)
host_name = opts[:host_name]
db_name = opts[:db_name]
userid = opts[:userid]
password = opts[:password]
url = "jdbc:oracle:thin:#{userid}/#{password}@#{host_name}:1521:#{db_name}"
$db = Sequel.connect(url)
endor:
DEFAULT = {
host_name: 'a_default_host_name',
db_name: 'a_default_db_name',
userid: 'a_default_userid',
password: 'a_default_password',
}
def connect_to_oracle( interface_opts = {} )
opts = DEFAULT.merge(interface_opts )
url = "jdbc:oracle:thin:%s/%s@%s:1521:%s" % [
opts[:userid],
opts[:password],
opts[:host_name],
opts[:db_name],
]
$db = Sequel.connect(url)
end
connect_to_oracle()
connect_to_oracle(:host_name => :xxxxxxxx)I prefer the version with
merge. So I get a constant with all default parameters in my documentation.Another advantage: I can easily add checks if my interface contains correct keys.
Example:
DEFAULT = {
host_name: 'a_default_host_name',
db_name: 'a_default_db_name',
userid: 'a_default_userid',
password: 'a_default_password',
}
def connect_to_oracle( myopts = {} )
(myopts.keys - DEFAULT.keys).each{|key|
puts "Undefined key #{key.inspect}"
}
opts = DEFAULT.merge(myopts)
url = "jdbc:oracle:thin:%s/%s@%s:1521:%s" % [
opts[:userid],
opts[:password],
opts[:host_name],
opts[:db_name],
]
#~ $db = Sequel.connect(url)
end
connect_to_oracle(:host_nam => :xxxxxxxx)My method call contains an error (forgotten 'e'), but when you call it, you get a warning
Undefined key host_nam. This often helps to detect errors. (in a real scenario I replace the puts with a logger-warning/error).Code Snippets
def connect_to_oracle( opts = {} )
host_name = opts[:host_name] ||'a_default_host_name'
db_name = opts[:db_name] || 'a_default_db_name'
userid = opts[:userid] || 'a_default_userid'
password = opts[:password] ||'a_default_password'
url = "jdbc:oracle:thin:#{userid}/#{password}@#{host_name}:1521:#{db_name}"
$db = Sequel.connect(url)
endDEFAULT = {
host_name: 'a_default_host_name',
db_name: 'a_default_db_name',
userid: 'a_default_userid',
password: 'a_default_password',
}
def connect_to_oracle( opts = {} )
opts = DEFAULT.merge(opts)
host_name = opts[:host_name]
db_name = opts[:db_name]
userid = opts[:userid]
password = opts[:password]
url = "jdbc:oracle:thin:#{userid}/#{password}@#{host_name}:1521:#{db_name}"
$db = Sequel.connect(url)
endDEFAULT = {
host_name: 'a_default_host_name',
db_name: 'a_default_db_name',
userid: 'a_default_userid',
password: 'a_default_password',
}
def connect_to_oracle( interface_opts = {} )
opts = DEFAULT.merge(interface_opts )
url = "jdbc:oracle:thin:%s/%s@%s:1521:%s" % [
opts[:userid],
opts[:password],
opts[:host_name],
opts[:db_name],
]
$db = Sequel.connect(url)
end
connect_to_oracle()
connect_to_oracle(:host_name => :xxxxxxxx)DEFAULT = {
host_name: 'a_default_host_name',
db_name: 'a_default_db_name',
userid: 'a_default_userid',
password: 'a_default_password',
}
def connect_to_oracle( myopts = {} )
(myopts.keys - DEFAULT.keys).each{|key|
puts "Undefined key #{key.inspect}"
}
opts = DEFAULT.merge(myopts)
url = "jdbc:oracle:thin:%s/%s@%s:1521:%s" % [
opts[:userid],
opts[:password],
opts[:host_name],
opts[:db_name],
]
#~ $db = Sequel.connect(url)
end
connect_to_oracle(:host_nam => :xxxxxxxx)Context
StackExchange Code Review Q#39017, answer score: 25
Revisions (0)
No revisions yet.