define Class#new in ruby to call #initialize

parent 779738b5
......@@ -107,7 +107,6 @@ typedef struct mrb_state {
struct mrb_irep **irep; /* program data array */
size_t irep_len, irep_capa;
mrb_sym init_sym;
struct RObject *top_self;
struct RClass *object_class; /* Object class */
struct RClass *class_class;
......@@ -173,6 +172,7 @@ void mrb_define_module_function(mrb_state*, struct RClass*, const char*, mrb_fun
void mrb_define_const(mrb_state*, struct RClass*, const char *name, mrb_value);
void mrb_undef_method(mrb_state*, struct RClass*, const char*);
void mrb_undef_class_method(mrb_state*, struct RClass*, const char*);
mrb_value mrb_obj_new(mrb_state *mrb, struct RClass *c, int argc, mrb_value *argv);
mrb_value mrb_instance_new(mrb_state *mrb, mrb_value cv);
struct RClass * mrb_class_new(mrb_state *mrb, struct RClass *super);
struct RClass * mrb_module_new(mrb_state *mrb);
......@@ -349,8 +349,6 @@ void mrb_print_error(mrb_state *mrb);
mrb_value mrb_yield(mrb_state *mrb, mrb_value b, mrb_value arg);
mrb_value mrb_yield_argv(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv);
mrb_value mrb_class_new_instance(mrb_state *mrb, int, mrb_value*, struct RClass *);
mrb_value mrb_class_new_instance_m(mrb_state *mrb, mrb_value klass);
void mrb_gc_protect(mrb_state *mrb, mrb_value obj);
mrb_value mrb_to_int(mrb_state *mrb, mrb_value val);
......
class Class
def new(*args,&b)
obj = self.alloc
obj.initialize(*args,&b)
obj
end
def self.new(*args)
obj = super
obj.inerited
obj
end
end
class Module
# 15.2.2.4.13
def attr_reader(*names)
names.each do |name|
name = name.to_s
raise(NameError, "#{name.inspect} is not allowed as an instance variable name") if name.include?('@') || name.include?('?') || name.include?('$')
attr_name = '@'+name
define_method(name){self.instance_variable_get(attr_name)}
end
......@@ -14,7 +27,7 @@ class Module
names.each do |name|
name = name.to_s
raise(NameError, "#{name.inspect} is not allowed as an instance variable name") if name.include?('@') || name.include?('?') || name.include?('$')
attr_name = '@'+name
name = (name+"=").intern
define_method(name){|v|self.instance_variable_set(attr_name,v)}
......
......@@ -1003,10 +1003,19 @@ mrb_method_search(mrb_state *mrb, struct RClass* c, mrb_sym mid)
return m;
}
void
mrb_obj_call_init(mrb_state *mrb, mrb_value obj, int argc, mrb_value *argv)
static mrb_value
mrb_instance_alloc(mrb_state *mrb, mrb_value cv)
{
mrb_funcall_argv(mrb, obj, mrb->init_sym, argc, argv);
struct RClass *c = mrb_class_ptr(cv);
struct RObject *o;
enum mrb_vtype ttype = MRB_INSTANCE_TT(c);
if (c->tt == MRB_TT_SCLASS)
mrb_raise(mrb, E_TYPE_ERROR, "can't create instance of singleton class");
if (ttype == 0) ttype = MRB_TT_OBJECT;
o = (struct RObject*)mrb_obj_alloc(mrb, ttype, c);
return mrb_obj_value(o);
}
/*
......@@ -1020,70 +1029,30 @@ mrb_obj_call_init(mrb_state *mrb, mrb_value obj, int argc, mrb_value *argv)
* an object is constructed using .new.
*
*/
mrb_value
mrb_class_new_instance(mrb_state *mrb, int argc, mrb_value *argv, struct RClass * klass)
{
mrb_value obj;
struct RClass * c = (struct RClass*)mrb_obj_alloc(mrb, klass->tt, klass);
c->super = klass;
obj = mrb_obj_value(c);
mrb_obj_call_init(mrb, obj, argc, argv);
return obj;
}
mrb_value
mrb_class_new_instance_m(mrb_state *mrb, mrb_value klass)
{
mrb_value *argv;
mrb_value blk;
struct RClass *k = mrb_class_ptr(klass);
struct RClass *c;
int argc;
mrb_value obj;
mrb_get_args(mrb, "*&", &argv, &argc, &blk);
c = (struct RClass*)mrb_obj_alloc(mrb, k->tt, k);
c->super = k;
obj = mrb_obj_value(c);
mrb_funcall_with_block(mrb, obj, mrb->init_sym, argc, argv, blk);
return obj;
}
mrb_value
mrb_instance_new(mrb_state *mrb, mrb_value cv)
{
struct RClass *c = mrb_class_ptr(cv);
struct RObject *o;
enum mrb_vtype ttype = MRB_INSTANCE_TT(c);
mrb_value obj, blk;
mrb_value *argv;
int argc;
if (c->tt == MRB_TT_SCLASS)
mrb_raise(mrb, E_TYPE_ERROR, "can't create instance of singleton class");
if (ttype == 0) ttype = MRB_TT_OBJECT;
o = (struct RObject*)mrb_obj_alloc(mrb, ttype, c);
obj = mrb_obj_value(o);
obj = mrb_instance_alloc(mrb, cv);
mrb_get_args(mrb, "*&", &argv, &argc, &blk);
mrb_funcall_with_block(mrb, obj, mrb->init_sym, argc, argv, blk);
mrb_funcall_with_block(mrb, obj, mrb_intern(mrb, "initialize"), argc, argv, blk);
return obj;
}
mrb_value
mrb_class_new_class(mrb_state *mrb, mrb_value cv)
mrb_obj_new(mrb_state *mrb, struct RClass *c, int argc, mrb_value *argv)
{
mrb_value super;
struct RClass *new_class;
mrb_value obj;
if (mrb_get_args(mrb, "|o", &super) == 0) {
super = mrb_obj_value(mrb->object_class);
}
new_class = mrb_class_new(mrb, mrb_class_ptr(super));
mrb_funcall(mrb, super, "inherited", 1, mrb_obj_value(new_class));
return mrb_obj_value(new_class);
obj = mrb_instance_alloc(mrb, mrb_obj_value(c));
mrb_funcall_argv(mrb, obj, mrb_intern(mrb, "initialize"), argc, argv);
return obj;
}
mrb_value
......@@ -1902,8 +1871,8 @@ mrb_init_class(mrb_state *mrb)
mrb_define_method(mrb, bob, "!", mrb_bob_not, MRB_ARGS_NONE());
mrb_define_method(mrb, bob, "method_missing", mrb_bob_missing, MRB_ARGS_ANY()); /* 15.3.1.3.30 */
mrb_define_class_method(mrb, cls, "new", mrb_class_new_class, MRB_ARGS_ANY());
mrb_define_method(mrb, cls, "superclass", mrb_class_superclass, MRB_ARGS_NONE()); /* 15.2.3.3.4 */
mrb_define_method(mrb, cls, "alloc", mrb_instance_alloc, MRB_ARGS_NONE());
mrb_define_method(mrb, cls, "new", mrb_instance_new, MRB_ARGS_ANY()); /* 15.2.3.3.3 */
mrb_define_method(mrb, cls, "inherited", mrb_bob_init, MRB_ARGS_REQ(1));
......
......@@ -307,7 +307,7 @@ mrb_name_error(mrb_state *mrb, mrb_sym id, const char *fmt, ...)
va_end(args);
argv[1] = mrb_symbol_value(id);
exc = mrb_class_new_instance(mrb, 2, argv, E_NAME_ERROR);
exc = mrb_obj_new(mrb, E_NAME_ERROR, 2, argv);
mrb_exc_raise(mrb, exc);
}
......
......@@ -452,5 +452,4 @@ mrb_init_symbol(mrb_state *mrb)
mrb_define_method(mrb, sym, "to_sym", sym_to_sym, MRB_ARGS_NONE()); /* 15.2.11.3.4 */
mrb_define_method(mrb, sym, "inspect", sym_inspect, MRB_ARGS_NONE()); /* 15.2.11.3.5(x) */
mrb_define_method(mrb, sym, "<=>", sym_cmp, MRB_ARGS_REQ(1));
mrb->init_sym = mrb_intern2(mrb, "initialize", 10);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment