diff options
author | Ufuk Kayserilioglu <[email protected]> | 2022-12-22 02:27:38 +0200 |
---|---|---|
committer | <[email protected]> | 2022-12-21 16:27:38 -0800 |
commit | 99cee85775bc5656b942bf4e1b0568a8f40addcd () | |
tree | 2411e0b27cfc55a559a50ac28eb1e0acec202e6f | |
parent | 398aaed2f0e56a81c5c15cc1126b6bbba79ffec0 (diff) |
Add copy with changes functionality for Data objects (#6766)
Implements [Feature #19000] This commit adds copy with changes functionality for `Data` objects using a new method `Data#with`. Since Data objects are immutable, the only way to change them is by creating a copy. This PR adds a `with` method for `Data` class instances that optionally takes keyword arguments. If the `with` method is called with no arguments, the behaviour is the same as the `Kernel#dup` method, i.e. a new shallow copy is created with no field values changed. However, if keyword arguments are supplied to the `with` method, then the copy is created with the specified field values changed. For example: ```ruby Point = Data.define(:x, :y) point = Point.new(x: 1, y: 2) point.with(x: 3) # => #<data Point x: 3, y: 2> ``` Passing positional arguments to `with` or passing keyword arguments to it that do not correspond to any of the members of the Data class will raise an `ArgumentError`. Co-authored-by: Alan Wu <[email protected]>
Notes: Merged-By: k0kubun <[email protected]>
-rw-r--r-- | struct.c | 59 | ||||
-rw-r--r-- | test/ruby/test_data.rb | 59 |
2 files changed, 118 insertions, 0 deletions
@@ -1834,6 +1834,63 @@ rb_data_init_copy(VALUE copy, VALUE s) /* * call-seq: * inspect -> string * to_s -> string * @@ -2205,6 +2262,8 @@ InitVM_Struct(void) rb_define_method(rb_cData, "deconstruct", rb_data_deconstruct, 0); rb_define_method(rb_cData, "deconstruct_keys", rb_data_deconstruct_keys, 1); } #undef rb_intern @@ -158,6 +158,65 @@ class TestData < Test::Unit::TestCase assert_not_operator(o1, :eql?, o3) end def test_memberless klass = Data.define |