在 ruby 中设置了属性的对象副本
Copy of object with attribute set in ruby
是否可以 return 在 Ruby 中创建具有属性集的对象副本?
当然可以定义一个方法来做这个-
class URI::Generic
def with_query(new_query)
ret = self.dup
ret.query = new_query
ret
end
end
但是处理每个属性可能会有点乏味。
您可以使用选项散列来传递多个 attribute-value 对。这是一个说明性的例子。
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:关于如何实现options hash的可能很少variations,但是,方法的本质或多或少是相同的。
是否可以 return 在 Ruby 中创建具有属性集的对象副本?
当然可以定义一个方法来做这个-
class URI::Generic
def with_query(new_query)
ret = self.dup
ret.query = new_query
ret
end
end
但是处理每个属性可能会有点乏味。
您可以使用选项散列来传递多个 attribute-value 对。这是一个说明性的例子。
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:关于如何实现options hash的可能很少variations,但是,方法的本质或多或少是相同的。