mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Fix Class inherited hook ordering
In CRuby the inherited method is invoked before Class.new yields to the block. An "already initialized error" exception is also removed since the inherited method is now invoked before initialization and can set instance variables on a class.
This commit is contained in:
+1
-5
@@ -3077,10 +3077,6 @@ mrb_class_initialize(mrb_state *mrb, mrb_value obj)
|
||||
{
|
||||
struct RClass *c = mrb_class_ptr(obj);
|
||||
|
||||
if (c->iv) {
|
||||
mrb_raise(mrb, E_TYPE_ERROR, "already initialized class");
|
||||
}
|
||||
|
||||
mrb_value a, b;
|
||||
mrb_get_args(mrb, "|C&", &a, &b);
|
||||
if (!mrb_nil_p(b)) {
|
||||
@@ -3099,6 +3095,7 @@ mrb_class_new_class(mrb_state *mrb, mrb_value cv)
|
||||
super = mrb_obj_value(mrb->object_class);
|
||||
}
|
||||
mrb_value new_class = mrb_obj_value(mrb_class_new(mrb, mrb_class_ptr(super)));
|
||||
mrb_class_inherited(mrb, mrb_class_ptr(super), mrb_class_ptr(new_class));
|
||||
mrb_sym mid = MRB_SYM(initialize);
|
||||
if (mrb_func_basic_p(mrb, new_class, mid, mrb_class_initialize)) {
|
||||
mrb_class_initialize(mrb, new_class);
|
||||
@@ -3106,7 +3103,6 @@ mrb_class_new_class(mrb_state *mrb, mrb_value cv)
|
||||
else {
|
||||
mrb_funcall_with_block(mrb, new_class, mid, n, &super, blk);
|
||||
}
|
||||
mrb_class_inherited(mrb, mrb_class_ptr(super), mrb_class_ptr(new_class));
|
||||
return new_class;
|
||||
}
|
||||
|
||||
|
||||
@@ -503,3 +503,39 @@ assert('module with extended callback') do
|
||||
assert_true BarBeingExtended.respond_to?(:answer)
|
||||
assert_equal 42, BarBeingExtended.answer
|
||||
end
|
||||
|
||||
assert("inherited hook runs before block body") do
|
||||
class A
|
||||
def self.values
|
||||
@values ||= []
|
||||
end
|
||||
|
||||
def self.inherited(mod)
|
||||
mod.values << 1
|
||||
end
|
||||
end
|
||||
|
||||
klass = Class.new(A) do
|
||||
self.values << 2
|
||||
end
|
||||
|
||||
assert_equal [1, 2], klass.values
|
||||
end
|
||||
|
||||
assert("inherited hook runs before class body") do
|
||||
class A
|
||||
def self.values
|
||||
@values ||= []
|
||||
end
|
||||
|
||||
def self.inherited(mod)
|
||||
mod.values << 1
|
||||
end
|
||||
end
|
||||
|
||||
class B < A
|
||||
self.values << 2
|
||||
end
|
||||
|
||||
assert_equal [1, 2], B.values
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user