ootoovak
6/19/2013 - 3:30 AM

Don't recreate another object if you don't need to.

Don't recreate another object if you don't need to.

# This one works as I originally wanted but requires a Class check and modifying new with I'm
# pretty sure can lead to bad things given how Ruby handles new and initialize.

class MyClass
   attr_accessor :name
   attr_accessor :description

   def self.new(args = {})
     args.is_a?(MyClass) ? args : super(args)
   end

   def initialize(args = {})
     @name = args.fetch(:name, '')
     @description = args.fetch(:description, '')
   end

   def fetch(key, default_value)
     send(key) || default_value
   end
end
# Good old Rubber Duck Debugging
# Will only pass 1 of 2 tests

class MyClass
  attr_accessor :name
  attr_accessor :description

  def initialize(args = {})
    @name = args.fetch(:name, '')
    @description = args.fetch(:description, '')
  end
  
  def fetch(key, default_value)
    send(key) || default_value
  end
end
# Want to pass in a hash or instance of object. Was hoping to avoid is_a? or creating a new object but
# think that can only be done with is_a? or overriding new. Also, I might be missing the point as 
# avoiding is_a? should mean I am using Duck Typing but if I'm using Duck Typing then I shouldn't be 
# checking object equality anyway. See RSpec test for details.

describe MyClass do
  let(:hash) { { name: 'Duck Type', description: 'Quacks like a duck?' } }
  
  before do
    @my_instance_1 = MyClass.new(hash)
    @my_instance_2 = MyClass.new(@my_instance_1)
  end

  it 'this is preferable' do
    @my_instance_1.should equal(@my_instance_2)
  end
  
  it 'this is ok' do
    @my_instance_1.should eq(@my_instance_2)
  end
end

# Possilbe solutions involve overriding MyClass.new or buidling a constructor
# http://stackoverflow.com/questions/4888786/how-can-i-change-the-return-value-of-a-class-constructor-in-ruby