I have the following code:
class A
attr_reader :x, :y
private_class_method :new
def self.with_data
a = new
a.x = 2
a.y = 'sid'
a
end
end
The intent is to restrict changing values of x
and y
variables once the class is initialized through the factory method with_data
. However, I want this to be allowed when the object is initialized from within the class, as evident from the code above.
But I am getting the following error when I invoke obj = A.with_data
:
NoMethodError: undefined method `x='
Should't this be allowed from inside class? Do I need to define attr_writer
for this? That would jeopardize encapsulation.
Also, I don't want to define a private setter method for each attribute in the class, as it might run into upto 30 instance level variables. Does ruby provide any feature to get around this?
Versions: Ruby 1.9.3
So what you need in your case is Object#instance_variable_set
:
class A
attr_reader :x, :y
private_class_method :new
def self.with_data
a = new
a.instance_variable_set(:@x, 2)
a.instance_variable_set(:@y, 'sid')
a
end
end
Usage:
a = A.with_data
#=> #<A:0x007ff37c979d30 @x=2, @y="sid">
a.x
#=> 2
a.x = 3
#=> NoMethodError: undefined method `x=' for #<A:0x007ff37c979d30 @x=2, @y="sid">