Faling Dutchman
Faling Dutchman

Reputation: 261

Ruby class initialization

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

Answers (1)

Tom
Tom

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.

Creating a new Object - Usage Examples

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

Related Questions