Feature #12719 ยป struct_merge.patch
ChangeLog | ||
---|---|---|
Fri Sep 2 17:27:31 2016 Matthew Mongeau <halogenandtoast@gmail.com>
|
||
* struct.c (rb_struct_update): Add Struct#merge and Struct#merge!
|
||
for updating structs
|
||
Fri Sep 2 16:06:59 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||
* internal.h (MEMO_V1_SET, MEMO_V2_SET): fix typos. use the macro
|
struct.c | ||
---|---|---|
return RSTRUCT_GET(s, i);
|
||
}
|
||
static int
|
||
value_update(VALUE key, VALUE value, VALUE s)
|
||
{
|
||
rb_struct_aset(s, key, value);
|
||
return ST_CONTINUE;
|
||
}
|
||
/*
|
||
* call-seq:
|
||
* struct.merge!(hash) -> struct
|
||
*
|
||
* Updates the values of the struct using the keys and values of the hash
|
||
*
|
||
* Point = Struct.new(:x, :y)
|
||
* hash = { "x" => 5 }
|
||
* point = Point.new(1, 2)
|
||
* point.merge!(hash)
|
||
*
|
||
* point.x #=> 5
|
||
*/
|
||
VALUE
|
||
rb_struct_update(VALUE self, VALUE hash)
|
||
{
|
||
VALUE converted_hash = rb_convert_type(hash, T_HASH, "Hash", "to_hash");
|
||
rb_hash_foreach(converted_hash, value_update, self);
|
||
return self;
|
||
}
|
||
/*
|
||
* call-seq:
|
||
* struct.merge(hash) -> new_struct
|
||
*
|
||
* Returns a new struct with updated values using the keys and values of
|
||
* the hash
|
||
*
|
||
* Point = Struct.new(:x, :y)
|
||
* p = Point.new(1, 2)
|
||
* p2 = p.merge(y: 20)
|
||
*
|
||
* p.y #=> 2
|
||
* p2.y #=> 20
|
||
*/
|
||
VALUE
|
||
rb_struct_merge(VALUE self, VALUE hash)
|
||
{
|
||
VALUE dup = rb_obj_dup(self);
|
||
return rb_struct_update(dup, hash);
|
||
}
|
||
/*
|
||
* call-seq:
|
||
* struct[member] = obj -> obj
|
||
... | ... | |
rb_define_method(rb_cStruct, "members", rb_struct_members_m, 0);
|
||
rb_define_method(rb_cStruct, "dig", rb_struct_dig, -1);
|
||
rb_define_method(rb_cStruct, "merge", rb_struct_merge, 1);
|
||
rb_define_method(rb_cStruct, "merge!", rb_struct_update, 1);
|
||
}
|
||
#undef rb_intern
|
test/ruby/test_struct.rb | ||
---|---|---|
assert_nil(o.dig(:b, 0))
|
||
end
|
||
def test_merge!
|
||
klass = @Struct.new(:a, :b)
|
||
o = klass.new(1, 2)
|
||
o.merge!(a: 10)
|
||
assert_equal(o.a, 10)
|
||
assert_equal(o.b, 2)
|
||
o.merge!("b" => 5)
|
||
assert_equal(o.b, 5)
|
||
assert_raise(TypeError) {
|
||
o.merge(0)
|
||
}
|
||
end
|
||
def test_merge
|
||
klass = @Struct.new(:a, :b)
|
||
o = klass.new(1, 2)
|
||
p = o.merge(a: 10)
|
||
assert_equal(p.a, 10)
|
||
assert_equal(p.b, 2)
|
||
assert_equal(o.a, 1)
|
||
assert_equal(o.b, 2)
|
||
assert_raise(TypeError) {
|
||
o.merge(0)
|
||
}
|
||
end
|
||
def test_new_dupilicate
|
||
bug12291 = '[ruby-core:74971] [Bug #12291]'
|
||
assert_raise_with_message(ArgumentError, /duplicate member/, bug12291) {
|