From a14a1a5626a4d8e661a3e606f8f92b8c455b9a04 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Thu, 1 Dec 2022 17:26:45 +0900 Subject: [PATCH] [Feature #19163] Data object should be frozen --- struct.c | 12 +++++++++++- test/ruby/test_data.rb | 8 ++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/struct.c b/struct.c index 6f67984cf2..def15b0186 100644 --- a/struct.c +++ b/struct.c @@ -1818,9 +1818,19 @@ rb_data_initialize_m(int argc, const VALUE *argv, VALUE self) if (arg.unknown_keywords != Qnil) { rb_exc_raise(rb_keyword_error_new("unknown", arg.unknown_keywords)); } + OBJ_FREEZE_RAW(self); return Qnil; } +/* :nodoc: */ +static VALUE +rb_data_init_copy(VALUE copy, VALUE s) +{ + copy = rb_struct_init_copy(copy, s); + RB_OBJ_FREEZE_RAW(copy); + return copy; +} + /* * call-seq: * inspect -> string @@ -2180,7 +2190,7 @@ InitVM_Struct(void) #endif rb_define_method(rb_cData, "initialize", rb_data_initialize_m, -1); - rb_define_method(rb_cData, "initialize_copy", rb_struct_init_copy, 1); + rb_define_method(rb_cData, "initialize_copy", rb_data_init_copy, 1); rb_define_method(rb_cData, "==", rb_data_equal, 1); rb_define_method(rb_cData, "eql?", rb_data_eql, 1); diff --git a/test/ruby/test_data.rb b/test/ruby/test_data.rb index f63b0236fb..b8dc55815b 100644 --- a/test/ruby/test_data.rb +++ b/test/ruby/test_data.rb @@ -62,6 +62,7 @@ class TestData < Test::Unit::TestCase assert_equal(1, test.foo) assert_equal(2, test.bar) assert_equal(test, klass.new(1, 2)) + assert_predicate(test, :frozen?) # Keywords test_kw = klass.new(foo: 1, bar: 2) @@ -169,4 +170,11 @@ class TestData < Test::Unit::TestCase assert_equal([], test.members) assert_equal({}, test.to_h) end + + def test_dup + klass = Data.define(:foo, :bar) + test = klass.new(foo: 1, bar: 2) + assert_equal(klass.new(foo: 1, bar: 2), test.dup) + assert_predicate(test.dup, :frozen?) + end end