Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I dynamically add an attr_reader

Tags:

ruby

I expect the following code to work as expected but it gives me a NoMethodError (private method `foo' called for #<MyClass...)

class MyClass
end

my_object = MyClass.new

my_object.instance_variable_set(:@foo, "bar")
MyClass.send("attr_reader", :foo)

puts my_object.foo

The problem is I'm using literally identical code in a larger application and it works exactly as I expect, but when I simplify it to this most basic example it fails.

(I understand there are many other ways to do what I'm doing in Ruby)

like image 351
Leroy22 Avatar asked Mar 31 '11 22:03

Leroy22


People also ask

How does Attr_reader work in Ruby?

Summary. 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.

What is ATTR reader?

An attribute reader returns the value of an instance variable. Another way of looking at this is that an attribute reader is a method that “exposes” an instance variable. It makes it accessible for others.

How do you use attribute accessor in Ruby?

In Ruby, object methods are public by default, while data is private. To access and modify data, we use the attr_reader and attr_writer . attr_accessor is a shortcut method when you need both attr_reader and attr_writer .


1 Answers

Use Module#class_eval:

By doing this, the block puts you in the context of MyClass, thus allowing you to call attr_reader

ruby-1.9.2-p136 :028 > my_object.instance_variable_set(:@foo, "bar")
 => "bar" 
ruby-1.9.2-p136 :029 > MyClass.class_eval{attr_reader :foo}
 => nil 
ruby-1.9.2-p136 :030 > my_object.foo
 => "bar" 
like image 120
Mike Lewis Avatar answered Oct 12 '22 11:10

Mike Lewis