diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2013-08-13 16:55:06 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2013-08-13 16:55:06 +0900 |
| commit | 6b015ec775571b2cbe96ae1545dd97991fbaf34a (patch) | |
| tree | 50cb903834f528d7d655a3011d26b6573b191d8d | |
| parent | 779738b597f445ed32b85be60a4f390a37ec139a (diff) | |
| download | mruby-6b015ec775571b2cbe96ae1545dd97991fbaf34a.tar.gz mruby-6b015ec775571b2cbe96ae1545dd97991fbaf34a.zip | |
define Class#new in ruby to call #initialize
| -rw-r--r-- | include/mruby.h | 4 | ||||
| -rw-r--r-- | mrblib/class.rb | 17 | ||||
| -rw-r--r-- | src/class.c | 73 | ||||
| -rw-r--r-- | src/error.c | 2 | ||||
| -rw-r--r-- | src/symbol.c | 1 |
5 files changed, 38 insertions, 59 deletions
diff --git a/include/mruby.h b/include/mruby.h index dcd2aa5fc..7674a87ff 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -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); diff --git a/mrblib/class.rb b/mrblib/class.rb index 6d624ee83..57aac2f93 100644 --- a/mrblib/class.rb +++ b/mrblib/class.rb @@ -1,10 +1,23 @@ +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)} diff --git a/src/class.c b/src/class.c index c10f7449b..dc3c49d5d 100644 --- a/src/class.c +++ b/src/class.c @@ -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)); diff --git a/src/error.c b/src/error.c index df4bbc866..98b49ad82 100644 --- a/src/error.c +++ b/src/error.c @@ -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); } diff --git a/src/symbol.c b/src/symbol.c index bd8dce7df..e49462e27 100644 --- a/src/symbol.c +++ b/src/symbol.c @@ -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); } |
