* eval.c (rb_block_pass): call a function with a block.  [new]

* eval.c (rb_method_new, rb_umethod_new): make anonymous Method
  object.  [new]


Index: eval.c
===================================================================
RCS file: //sharui/cvs/ruby/src/ruby/eval.c,v
retrieving revision 1.472
diff -u -2 -p -r1.472 eval.c
--- eval.c	2 Jul 2003 04:27:25 -0000	1.472
+++ eval.c	3 Jul 2003 09:27:39 -0000
@@ -7135,10 +7135,10 @@ proc_binding(proc)
 }
 
-static VALUE
-block_pass(self, node)
-    VALUE self;
-    NODE *node;
+VALUE
+rb_block_pass(func, arg, proc)
+    VALUE (*func) _((VALUE));
+    VALUE arg;
+    VALUE proc;
 {
-    VALUE proc = rb_eval(self, node->nd_body);	/* OK */
     VALUE b;
     struct BLOCK * volatile old_block;
@@ -7152,5 +7152,5 @@ block_pass(self, node)
     if (NIL_P(proc)) {
 	PUSH_ITER(ITER_NOT);
-	result = rb_eval(self, node->nd_iter);
+	result = (*func)(arg);
 	POP_ITER();
 	return result;
@@ -7189,5 +7189,5 @@ block_pass(self, node)
 	if (safe > ruby_safe_level)
 	    ruby_safe_level = safe;
-	result = rb_eval(self, node->nd_iter);
+	result = (*func)(arg);
     }
     POP_TAG();
@@ -7234,4 +7234,28 @@ block_pass(self, node)
 }
 
+struct block_arg {
+    VALUE self;
+    NODE *iter;
+};
+
+static VALUE
+call_block(arg)
+    struct block_arg *arg;
+{
+    return rb_eval(arg->self, arg->iter);
+}
+
+static VALUE
+block_pass(self, node)
+    VALUE self;
+    NODE *node;
+{
+    struct block_arg arg;
+    arg.self = self;
+    arg.iter = node->nd_iter;
+    return rb_block_pass((VALUE (*)_((VALUE)))call_block,
+			 (VALUE)&arg, rb_eval(self, node->nd_body));
+}
+
 struct METHOD {
     VALUE klass, rklass;
@@ -7251,4 +7275,48 @@ bm_mark(data)
 }
 
+VALUE
+rb_method_new(obj, func, argc)
+    VALUE obj;
+    VALUE (*func)();
+    int argc;
+{
+    VALUE method;
+    NODE *body;
+    struct METHOD *data;
+
+    method = Data_Make_Struct(rb_cMethod, struct METHOD, bm_mark, free, data);
+    data->rklass = data->klass = CLASS_OF(obj);
+    data->recv = obj;
+    data->oid = data->id = 0;
+    data->body = NEW_CFUNC(func, argc);
+    OBJ_INFECT(method, obj);
+
+    return method;
+}
+
+VALUE
+rb_umethod_new(klass, func, argc)
+    VALUE klass;
+    VALUE (*func)();
+    int argc;
+{
+    VALUE method;
+    NODE *body;
+    struct METHOD *data;
+
+    if (!rb_obj_is_kind_of(klass, rb_cModule)) {
+	rb_raise(rb_eTypeError, "wrong argument type %s (expected Class/Module)",
+		 rb_obj_classname(klass));
+    }
+    method = Data_Make_Struct(rb_cUnboundMethod, struct METHOD, bm_mark, free, data);
+    data->rklass = data->klass = klass;
+    data->recv = Qundef;
+    data->oid = data->id = 0;
+    data->body = NEW_CFUNC(func, argc);
+    OBJ_INFECT(method, klass);
+
+    return method;
+}
+
 static VALUE
 mnew(klass, obj, id, mklass)
@@ -7410,5 +7478,5 @@ umethod_bind(method, recv)
 	    rb_raise(rb_eTypeError, "singleton method called for a different object");
 	}
-	if (FL_TEST(CLASS_OF(recv), FL_SINGLETON) &&
+	if (data->oid && FL_TEST(CLASS_OF(recv), FL_SINGLETON) &&
 	    st_lookup(RCLASS(CLASS_OF(recv))->m_tbl, data->oid, 0)) {
 	    rb_raise(rb_eTypeError, "method `%s' overridden", rb_id2name(data->oid));
@@ -7505,6 +7573,8 @@ method_inspect(method)
 	}
     }
-    rb_str_buf_cat2(str, sharp);
-    rb_str_buf_cat2(str, rb_id2name(data->oid));
+    if (data->oid) {
+	rb_str_buf_cat2(str, sharp);
+	rb_str_buf_cat2(str, rb_id2name(data->oid));
+    }
     rb_str_buf_cat2(str, ">");
 
