Reputation: 261
I want to create an object that can be initialized in two different ways. I found 3 different way's of accomplishing the same thing, I want to know which of my methods is the best one, and if there is another better way of doing it.
Method
attr_accessor :id, :status, :dateTime
def initialize *args
if args.length == 1
puts args[0]
@id = args[0]['id']
@status = args[0]['status']
@dateTime = args[0]['dateTime']
else
@id = args[0]
@status = args[1]
@dateTime = args[2]
end
end
Method 2: (note that I need to set the parameters by hand on this one as second way)
attr_accessor :id, :status, :dateTime
def initialize hash = nil
if hash != nil
@id = hash['id']
@status = hash['status']
@dateTime = hash['dateTime']
end
end
Method 3: (note that I need to set the parameters by hand on this one as second way AND that it is almost the same as my second way, just not in the constructor)
attr_accessor :id, :status, :dateTime
def initialize
end
def self.create hash
if hash != nil
obj = Obj3.new
obj.id = hash['id']
obj.status = hash['status']
obj.dateTime = hash['dateTime']
return obj
end
end
Thanks in advance!
Upvotes: 3
Views: 4740
Reputation: 480
I would try using a hash for your constructor like the code below adapted from DRY Ruby Initialization with Hash Argument
class Example
attr_accessor :id, :status, :dateTime
def initialize args
args.each do |k,v|
instance_variable_set("@#{k}", v) unless v.nil?
end
end
end
That way setting each of your properties in the constructor becomes optional. As the instance_variable_set method will set each property if the has contains a value for it.
Which means you could support any number of ways to construct your object. The only downside is you might have to do more nil checking in your code but without more information it is hard to know.
To create a new object with this technique all you need to do is pass in a hash to your initialiser:
my_new_example = Example.new :id => 1, :status => 'live'
#=> #<Example: @id=1, @status='live'>
And its flexible enough to create multiple objects without certain properties with one constructor:
my_second_new_example = Example.new :id => 1
#=> #<Example: @id=1>
my_third_new_example = Example.new :status => 'nonlive', :dateTime => DateTime.new(2001,2,3)
#=> #<Example: @id=1, @dateTime=2001-02-03T00:00:00+00:00>
You can still update your properties once the objects have been created:
my_new_example.id = 24
Upvotes: 5