Reputation: 10564
I have a class that I want to put factory methods on to spit out a new instance based on one of two construction methods: either it can be constructed from data in memory, or data stored in a file.
What I would like to do is to encapsulate the logic of how the construction is performed inside the class, so I would like to have static class methods that are set up like this:
class MyAppModel
def initialize
#Absolutely nothing here - instances are not constructed externally with MyAppModel.new
end
def self.construct_from_some_other_object otherObject
inst = MyAppModel.new
inst.instance_variable_set("@some_non_published_var", otherObject.foo)
return inst
end
def self.construct_from_file file
inst = MyAppModel.new
inst.instance_variable_set("@some_non_published_var", get_it_from_file(file))
return inst
end
end
Is there no way to set @some_private_var on an instance of a class from the class itself without resorting to metaprogramming (instance_variable_set)? It seems like this pattern is not so esoteric as to require meta-poking variables into instances. I really don't intend to allow any class outside of MyAppModel to have access to some_published_var, so I don't want to use e.g. attr_accessor - it just feels like I'm missing something...
Upvotes: 8
Views: 7300
Reputation: 1241
Maybe using a constructor is the better way to achieve what you want, just make it protected if you don't want to create instances from the "outside"
class MyAppModel
class << self
# ensure that your constructor can't be called from the outside
protected :new
def construct_from_some_other_object(other_object)
new(other_object.foo)
end
def construct_from_file(file)
new(get_it_from_file(file))
end
end
def initialize(my_var)
@my_var = my_var
end
end
Upvotes: 11