Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I set an attr_accessor for a dynamic instance variable?

I dynamically created an instance variable within my class:

class Mine   attr_accessor :some_var    def intialize     @some_var = true   end    def my_number num     self.instance_variable_set "@my_#{num}", num   end end 

How do I make @my_#{num} now as an attr value?

e.g. I want to be able to do this:

dude = Mine.new dude.my_number 1 dude.my_1 => 1 
like image 412
eywu Avatar asked Feb 11 '11 00:02

eywu


People also ask

What is Attr_accessor?

attr_accessor is a shortcut method when you need both attr_reader and attr_writer . Since both reading and writing data are common, the idiomatic method attr_accessor is quite useful.

What does Attr_reader do in Ruby?

attr_reader and attr_writer in Ruby allow us to access and modify instance variables using the . notation by creating getter and setter methods automatically. These methods allow us to access instance variables from outside the scope of the class definition.

How do you create an instance variable in Ruby?

An instance variable in ruby has a name starting with @ symbol, and its content is restricted to whatever the object itself refers to. Two separate objects, even though they belong to the same class, are allowed to have different values for their instance variables.

What is Attr_accessible?

attr_accessible is used to identify attributes that are accessible by your controller methods makes a property available for mass-assignment.. It will only allow access to the attributes that you specify, denying the rest.


2 Answers

this answer doesn't pollutes the class space, example.. if i do mine.my_number 4 then the other instances of Mine will not get the my_4 method.. this happens because we use the singleton class of the object instead of the class.

class Mine   def my_number num     singleton_class.class_eval { attr_accessor "my_#{num}" }     send("my_#{num}=", num)   end end  a = Mine.new b = Mine.new a.my_number 10 #=> 10 a.my_10 #=> 10 b.my_10 #=> NoMethodError 
like image 144
Orlando Avatar answered Oct 16 '22 01:10

Orlando


This can be accomplished using __send__. Here:

class Mine   attr_accessor :some_var    def intialize     @some_var = true   end    def my_number num     self.class.__send__(:attr_accessor, "my_#{num}")     self.__send__("my_#{num}=", num)   end end  dude = Mine.new dude.my_number 1 puts dude.my_1  => 1 
like image 20
Dorkus Prime Avatar answered Oct 16 '22 01:10

Dorkus Prime