22

I want to use an options hash as input to a method in Ruby, but is there a way to quickly set all eponymous variables (i.e having the same name) instead of setting each individually?

So instead of doing the following:

class Connection
  def initialize(opts={})
    @host     = opts[:host]
    @user     = opts[:user]
    @password = opts[:password]
    @project  = opts[:project]
    # ad nauseum...

is there a one-liner that will assign each incoming option in the hash to the variable with the same name?

1

4 Answers 4

52
def initialize(opts={})
  opts.each { |k,v| instance_variable_set("@#{k}", v) }
end
2
  • Thanks, I just found this: stackoverflow.com/questions/9597249/… which is exactly what you are also saying. I will close my question as a duplicate, but upvote your answer. Commented Nov 9, 2012 at 6:56
  • 4
    Whitelisting the keys would be a good addition, a couple seconds to set up the whitelist now could save hours of debugging time later and help document the interface as a side effect. Commented Nov 9, 2012 at 7:31
4

This should give you what you're looking for:

def initialize(opts={})
  opts.each_pair do |key, value|
    send("#{key}=",value)
  end
end
1
  • 1
    This only works if you have setter methods via attr_accessor, attr_writer, or manually created setter methods
    – ptierno
    Commented Oct 7, 2015 at 20:31
1

you can do this with,

 @host, @user, @password, @project  = opts[:host], opts[:user], opts[:password], opts[:project]

hope this helps!

1

Besides Casper's solution, you could also use the instance_variables_from gem:

instance_variables_from(opts)

Not the answer you're looking for? Browse other questions tagged or ask your own question.