summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog11
-rw-r--r--eval.c23
-rw-r--r--intern.h1
-rw-r--r--node.h2
-rw-r--r--object.c12
5 files changed, 34 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog
index e4d649fca..cb5f972dc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+Tue Feb 10 20:49:07 2004 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * eval.c (method_proc): return bound Proc object. [ruby-dev:22854]
+
+ * eval.c (rb_mod_define_method): bind method body itself for Method
+ object.
+
+ * node.h (NODE_DMETHOD): deprecated.
+
+ * object.c (rb_class_inherited_p): export.
+
Tue Feb 10 16:43:50 2004 Nobuyoshi Nakada <nobu@ruby-lang.org>
* eval.c (umethod_bind): perge unused check. [ruby-dev:22850]
diff --git a/eval.c b/eval.c
index 0fcbf8fa4..9d46524f0 100644
--- a/eval.c
+++ b/eval.c
@@ -5437,10 +5437,6 @@ rb_call0(klass, recv, id, oid, argc, argv, body, nosuper)
result = rb_eval(recv, body);
break;
- case NODE_DMETHOD:
- result = method_call(argc, argv, umethod_bind(body->nd_cval, recv));
- break;
-
case NODE_BMETHOD:
result = proc_invoke(body->nd_cval, rb_ary_new4(argc, argv), recv, klass);
break;
@@ -8781,7 +8777,6 @@ method_arity(method)
case NODE_IVAR:
return INT2FIX(0);
case NODE_BMETHOD:
- case NODE_DMETHOD:
return proc_arity(body->nd_cval);
default:
body = body->nd_next; /* skip NODE_SCOPE */
@@ -8907,8 +8902,11 @@ method_proc(method)
struct METHOD *mdata;
struct BLOCK *bdata;
- proc = rb_iterate((VALUE(*)_((VALUE)))mproc, 0, bmcall, method);
Data_Get_Struct(method, struct METHOD, mdata);
+ if (nd_type(mdata->body) == NODE_BMETHOD) {
+ return mdata->body->nd_cval;
+ }
+ proc = rb_iterate((VALUE(*)_((VALUE)))mproc, 0, bmcall, method);
Data_Get_Struct(proc, struct BLOCK, bdata);
bdata->body->nd_file = mdata->body->nd_file;
nd_set_line(bdata->body, nd_line(mdata->body));
@@ -8991,7 +8989,18 @@ rb_mod_define_method(argc, argv, mod)
rb_raise(rb_eArgError, "wrong number of arguments(%d for 1)", argc);
}
if (RDATA(body)->dmark == (RUBY_DATA_FUNC)bm_mark) {
- node = NEW_DMETHOD(method_unbind(body));
+ struct METHOD *method = (struct METHOD *)DATA_PTR(body);
+ VALUE rklass = method->rklass;
+ if (rklass != mod) {
+ if (FL_TEST(rklass, FL_SINGLETON)) {
+ rb_raise(rb_eTypeError, "cannot bind singleton method to a different class");
+ }
+ if (RCLASS(rklass)->super && !RTEST(rb_class_inherited_p(mod, rklass))) {
+ rb_raise(rb_eTypeError, "bind argument must be a subclass of %s",
+ rb_class2name(rklass));
+ }
+ }
+ node = method->body;
}
else if (RDATA(body)->dmark == (RUBY_DATA_FUNC)blk_mark) {
struct BLOCK *block;
diff --git a/intern.h b/intern.h
index 6244e6aba..5a22b8cae 100644
--- a/intern.h
+++ b/intern.h
@@ -305,6 +305,7 @@ VALUE rb_obj_freeze _((VALUE));
VALUE rb_obj_id _((VALUE));
VALUE rb_obj_class _((VALUE));
VALUE rb_class_real _((VALUE));
+VALUE rb_class_inherited_p _((VALUE, VALUE));
VALUE rb_convert_type _((VALUE,int,const char*,const char*));
VALUE rb_check_convert_type _((VALUE,int,const char*,const char*));
VALUE rb_to_int _((VALUE));
diff --git a/node.h b/node.h
index ee953ca19..da71ee707 100644
--- a/node.h
+++ b/node.h
@@ -118,7 +118,6 @@ enum node_type {
#ifdef C_ALLOCA
NODE_ALLOCA,
#endif
- NODE_DMETHOD,
NODE_BMETHOD,
NODE_MEMO,
NODE_IFUNC,
@@ -335,7 +334,6 @@ typedef struct RNode {
#define NEW_DEFINED(e) NEW_NODE(NODE_DEFINED,e,0,0)
#define NEW_PREEXE(b) NEW_SCOPE(b)
#define NEW_POSTEXE() NEW_NODE(NODE_POSTEXE,0,0,0)
-#define NEW_DMETHOD(b) NEW_NODE(NODE_DMETHOD,0,0,b)
#define NEW_BMETHOD(b) NEW_NODE(NODE_BMETHOD,0,0,b)
#define NEW_ATTRASGN(r,m,a) NEW_NODE(NODE_ATTRASGN,r,m,a)
diff --git a/object.c b/object.c
index f996aa992..bbc9ec539 100644
--- a/object.c
+++ b/object.c
@@ -1269,8 +1269,8 @@ rb_mod_eqq(mod, arg)
*
*/
-static VALUE
-rb_mod_le(mod, arg)
+VALUE
+rb_class_inherited_p(mod, arg)
VALUE mod, arg;
{
VALUE start = mod;
@@ -1314,7 +1314,7 @@ rb_mod_lt(mod, arg)
VALUE mod, arg;
{
if (mod == arg) return Qfalse;
- return rb_mod_le(mod, arg);
+ return rb_class_inherited_p(mod, arg);
}
@@ -1342,7 +1342,7 @@ rb_mod_ge(mod, arg)
rb_raise(rb_eTypeError, "compared with non class/module");
}
- return rb_mod_le(arg, mod);
+ return rb_class_inherited_p(arg, mod);
}
/*
@@ -1390,7 +1390,7 @@ rb_mod_cmp(mod, arg)
return Qnil;
}
- cmp = rb_mod_le(mod, arg);
+ cmp = rb_class_inherited_p(mod, arg);
if (NIL_P(cmp)) return Qnil;
if (cmp) {
return INT2FIX(-1);
@@ -2569,7 +2569,7 @@ Init_Object()
rb_define_method(rb_cModule, "==", rb_obj_equal, 1);
rb_define_method(rb_cModule, "<=>", rb_mod_cmp, 1);
rb_define_method(rb_cModule, "<", rb_mod_lt, 1);
- rb_define_method(rb_cModule, "<=", rb_mod_le, 1);
+ rb_define_method(rb_cModule, "<=", rb_class_inherited_p, 1);
rb_define_method(rb_cModule, ">", rb_mod_gt, 1);
rb_define_method(rb_cModule, ">=", rb_mod_ge, 1);
rb_define_method(rb_cModule, "initialize_copy", rb_mod_init_copy, 1); /* in class.c */