diff options
| author | take_cheeze <[email protected]> | 2017-04-21 17:23:54 +0900 |
|---|---|---|
| committer | take_cheeze <[email protected]> | 2017-04-21 17:23:54 +0900 |
| commit | da5b7fa769442b41a3dc67f2a8ab9db399910508 (patch) | |
| tree | 57391641e35c9e7966a6591048e09593de8cb93b /mrbgems/mruby-struct | |
| parent | 94bcdca64fb08e3724c1a5cf6ce25f6f9c6e041e (diff) | |
| download | mruby-da5b7fa769442b41a3dc67f2a8ab9db399910508.tar.gz mruby-da5b7fa769442b41a3dc67f2a8ab9db399910508.zip | |
Support freeze in `Struct`.
Diffstat (limited to 'mrbgems/mruby-struct')
| -rw-r--r-- | mrbgems/mruby-struct/src/struct.c | 14 | ||||
| -rw-r--r-- | mrbgems/mruby-struct/test/struct.rb | 13 |
2 files changed, 25 insertions, 2 deletions
diff --git a/mrbgems/mruby-struct/src/struct.c b/mrbgems/mruby-struct/src/struct.c index b28fa1da7..c5fd34754 100644 --- a/mrbgems/mruby-struct/src/struct.c +++ b/mrbgems/mruby-struct/src/struct.c @@ -84,6 +84,16 @@ mrb_struct_s_members_m(mrb_state *mrb, mrb_value klass) return ary; } +static void +mrb_struct_modify(mrb_state *mrb, mrb_value strct) +{ + if (MRB_FROZEN_P(mrb_basic_ptr(strct))) { + mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen struct"); + } + + mrb_write_barrier(mrb, mrb_basic_ptr(strct)); +} + /* 15.2.18.4.6 */ /* * call-seq: @@ -448,8 +458,8 @@ mrb_struct_aset_sym(mrb_state *mrb, mrb_value s, mrb_sym id, mrb_value val) ptr_members = RARRAY_PTR(members); for (i=0; i<len; i++) { if (mrb_symbol(ptr_members[i]) == id) { + mrb_struct_modify(mrb, s); ptr[i] = val; - mrb_write_barrier(mrb, (struct RBasic*)mrb_ptr(s)); return val; } } @@ -512,7 +522,7 @@ mrb_struct_aset(mrb_state *mrb, mrb_value s) "offset %S too large for struct(size:%S)", mrb_fixnum_value(i), mrb_fixnum_value(RSTRUCT_LEN(s))); } - mrb_write_barrier(mrb, (struct RBasic*)mrb_ptr(s)); + mrb_struct_modify(mrb, s); return RSTRUCT_PTR(s)[i] = val; } diff --git a/mrbgems/mruby-struct/test/struct.rb b/mrbgems/mruby-struct/test/struct.rb index 1c0939e7f..421fe4b5d 100644 --- a/mrbgems/mruby-struct/test/struct.rb +++ b/mrbgems/mruby-struct/test/struct.rb @@ -197,3 +197,16 @@ assert("Struct.new generates subclass of Struct") do Struct = original_struct end end + +assert 'Struct#freeze' do + c = Struct.new :m + + o = c.new + o.m = :test + assert_equal :test, o.m + + o.freeze + assert_raise(RuntimeError) { o.m = :modify } + assert_raise(RuntimeError) { o[:m] = :modify } + assert_equal :test, o.m +end |
