Andrei Botalov
Andrei Botalov

Reputation: 21096

Is it possible to get access to keyword arguments as a Hash in Ruby?

I know I can do:

class Parent
  def initialize(args)
    args.each do |k,v|
      instance_variable_set("@#{k}", v)
    end
  end
end
class A < Parent
  def initialize(attrs)
    super(attrs)
  end
end

But I'd want to use keyword arguments to make more clear which hash keys method may accept (and have validation saying that this key isn't supported).

So I can write:

class A
  def initialize(param1: 3, param2: 4)
    @param1 = param1
    @param2 = param2
  end
end

But is it possible to write something shorter instead of @x = x; @y = y; ... to initialize instance variables from passed keyword arguments? Is it possible to get access to passed keyword arguments as a Hash?

Upvotes: 8

Views: 1683

Answers (1)

Dogbert
Dogbert

Reputation: 222040

Not something I would recommend using (because eval!), but this is the only way I can think of, as I don't think there's a way to get the value of a local variable without eval.

class A
  def initialize(param1: 3, param2: 4)
    method(__method__).parameters.each do |type, name|
      if type == :key
        instance_variable_set "@#{name}", eval("#{name}")
      end
    end
  end
end

p A.new param1: 20, param2: 23
p A.new

Output:

#<A:0x007fd7e21008d0 @param1=20, @param2=23>
#<A:0x007fd7e2100218 @param1=3, @param2=4>

method returns a Method object for the passed in symbol, __method__ returns the name of the current method, and Method#parameters returns an array describing the parameters the method accepts. Here I only set the parameters which have the type :key (named params).

Upvotes: 5

Related Questions