Search code examples
rubycopygreedy

Copy object without any pointers in Ruby


I am trying to write a Greedy Algorithm for a certain problem. Simplified it looks like this:

There's an object called Foo with an randomized attribute called value and a method that changes this value change_value in a way that depends on an integer input

class Foo
  def initialize
    value = rand(1,10)
  end

  def change_value(input)
    #changes the value in a certain way
  end
end

Now the Greedy Algorithmus just gets the new value of Foo for all possible inputs and return the best input.

foo = Foo.new

best_value = 0
best_input = 0

(1..inputs).each do |k|
  temp_foo = foo.clone
  temp_foo.change_value(k)
  if temp_foo.value>best_value
    best_value = temp_foo.value
    best_input = k
  end
end

Foo.change_value(best_input)

The code works nearly as intended. The big problem is that the change_value-method within the each-funtion alters the temp_foo and the foo. What do I need to change to makes those objects completly dependent of each other? I also tried .dub by the way.


Solution

  • I think #clone or #dup won't work because they will share a reference to @value inside Foo.

    In any case, you can do it more readably by changing Foo#change_value so it doesn't actually mutate the object but returns a copy:

    class Foo
      def initialize(value = nil)
        @value = value || rand(10)
      end
    
      def change_value(input)
        # returns a new Foo instance
        Foo.new(@value + 1)
      end
    
      def value
        @value
      end
    end
    

    Because you're copying data in any case, using an immutable object (Value Object) is more general than some kind of deep clone.