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?

mydoghasworms
  • 18,233
  • 11
  • 61
  • 95
  • possible duplicate of [in Ruby can I automatically populate instance variables somehow in the initialize method?](http://stackoverflow.com/questions/9597249/in-ruby-can-i-automatically-populate-instance-variables-somehow-in-the-initializ) – mydoghasworms Nov 09 '12 at 06:56

4 Answers4

52
def initialize(opts={})
  opts.each { |k,v| instance_variable_set("@#{k}", v) }
end
Casper
  • 33,403
  • 4
  • 84
  • 79
  • Thanks, I just found this: http://stackoverflow.com/questions/9597249/in-ruby-can-i-automatically-populate-instance-variables-somehow-in-the-initializ/10855962 which is exactly what you are also saying. I will close my question as a duplicate, but upvote your answer. – mydoghasworms Nov 09 '12 at 06: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. – mu is too short Nov 09 '12 at 07: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
brentmc79
  • 2,531
  • 2
  • 16
  • 13
  • 1
    This only works if you have `setter` methods via `attr_accessor`, `attr_writer`, or manually created `setter` methods – ptierno Oct 07 '15 at 20:31
1

you can do this with,

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

hope this helps!

cweston
  • 11,297
  • 19
  • 82
  • 107
maximus ツ
  • 7,949
  • 3
  • 25
  • 54
1

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

instance_variables_from(opts)
J-_-L
  • 9,079
  • 2
  • 40
  • 37