1

Is it possible to return create copy of object with an attribute set, in Ruby?

Of course, a method can be defined to do this -

class URI::Generic
  def with_query(new_query)
    ret = self.dup
    ret.query = new_query
    ret
  end
end

But this might get a bit tedious to do with every attribute.

George Simms
  • 3,930
  • 4
  • 21
  • 35

1 Answers1

2

You can use options hash to pass multiple attribute-value pairs. Here is an illustrative example.

class Sample
  attr_accessor :foo, :bar

  def with(**options)
    dup.tap do |copy|
        options.each do |attr, value|
            m = copy.method("#{attr}=") rescue nil
            m.call(value) if m
        end
    end
  end

end


obj1 = Sample.new
#=> #<Sample:0x000000029186e0>
obj2 = obj1.with(foo: "Hello")
#=> #<Sample:0x00000002918550 @foo="Hello">
obj3 = obj2.with(foo: "Hello", bar: "World")
#=> #<Sample:0x00000002918348 @foo="Hello", @bar="World">

# Options hash is optional - can be used to just dup the object as well
obj4 = obj3.with
#=> #<Sample:0x0000000293bf00 @foo="Hello", @bar="World">

PS: There may be few variations on how to implement options hash, however, essence of approach will be more or less same.

Community
  • 1
  • 1
Wand Maker
  • 18,476
  • 8
  • 53
  • 87