summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2017-04-21 22:28:32 +0900
committerGitHub <[email protected]>2017-04-21 22:28:32 +0900
commitc900fff9a15dcc1608927705b85dd1b4499aaf24 (patch)
tree4dd015bad11c0f94840a922f2a26716d764e4aa0
parentc73da29aeefb0ad159e206b2b492ef50f826a9c3 (diff)
parentda5b7fa769442b41a3dc67f2a8ab9db399910508 (diff)
downloadmruby-c900fff9a15dcc1608927705b85dd1b4499aaf24.tar.gz
mruby-c900fff9a15dcc1608927705b85dd1b4499aaf24.zip
Merge pull request #3623 from take-cheeze/struct_freeze
Support `freeze` method in `Struct`.
-rw-r--r--mrbgems/mruby-struct/src/struct.c14
-rw-r--r--mrbgems/mruby-struct/test/struct.rb13
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