mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Support freeze in Struct.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user