Julio Carvalho
Julio Carvalho

Reputation: 151

Ruby: How to create attr_accessor on the fly

I want to know how to create attr_accessor on the fly. Is it possible to do something like:

attr_accessor "@#{key}" 

inside the initialize method?

module Mymodule
  def initialize(parameters = {})
    parameters.each do |key, value|
      instance_variable_set("@#{key}", value) unless value.nil?
    end
  end
end

class Myclass
  include Mymodule
end

clazz = Myclass.new attr1: "Arg1", attr2: "Arg2", attr3: "Arg3"
  # => #<Myclass:0x43f6050 @attr1="Arg1", @attr2="Arg2", @attr3="Arg3">

clazz.attr1
  # !> NoMethodError: undefined method `attr1' for #<Myclass:0x43f6050 @attr1="Arg1", @attr2="Arg2", @attr3="Arg3">

clazz.attr1="ATTR1"
  # !> NoMethodError: undefined method `attr1=' for #<Myclass:0x43f6050 @attr1="Arg1", @attr2="Arg2", @attr3="Arg3">

Upvotes: 2

Views: 681

Answers (1)

ndnenkov
ndnenkov

Reputation: 36101

You can define per instance accessors by calling attr_accessor on that instance's singleton class.

class Structy
  def initialize(parameters = {})
    parameters.each do |key, value|
      singleton_class.send :attr_accessor, key
      instance_variable_set "@#{key}", value
    end
  end
end

Upvotes: 8

Related Questions