Project

General

Profile

Feature #12719 ยป struct_merge.patch

halogenandtoast (Matthew Mongeau), 09/05/2016 02:55 AM

View differences:

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) {
    (1-1/1)