[前][次][番号順一覧][スレッド一覧]

ruby-changes:5106

From: knu <ko1@a...>
Date: Mon, 26 May 2008 10:14:06 +0900 (JST)
Subject: [ruby-changes:5106] Ruby:r16601 (ruby_1_8): * eval.c (yield_under, yield_under_i, yield_args_under_i)

knu	2008-05-26 10:13:53 +0900 (Mon, 26 May 2008)

  New Revision: 16601

  Modified files:
    branches/ruby_1_8/ChangeLog
    branches/ruby_1_8/eval.c

  Log:
    * eval.c (yield_under, yield_under_i, yield_args_under_i)
      (specific_eval, rb_obj_instance_exec, Init_eval): Implement
      Object#instance_exec(), a 1.9 feature.


  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8/ChangeLog?r1=16601&r2=16600&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8/eval.c?r1=16601&r2=16600&diff_format=u

Index: ruby_1_8/ChangeLog
===================================================================
--- ruby_1_8/ChangeLog	(revision 16600)
+++ ruby_1_8/ChangeLog	(revision 16601)
@@ -1,3 +1,9 @@
+Mon May 26 10:03:35 2008  Akinori MUSHA  <knu@i...>
+
+	* eval.c (yield_under, yield_under_i, yield_args_under_i)
+	  (specific_eval, rb_obj_instance_exec, Init_eval): Implement
+	  Object#instance_exec(), a 1.9 feature.
+
 Mon May 26 08:00:52 2008  Akinori MUSHA  <knu@i...>
 
 	* marshal.c (r_object0, Init_marshal): Fix the garbled s_call
Index: ruby_1_8/eval.c
===================================================================
--- ruby_1_8/eval.c	(revision 16600)
+++ ruby_1_8/eval.c	(revision 16601)
@@ -6746,12 +6746,28 @@
     return rb_yield_0(self, self, ruby_class, YIELD_PUBLIC_DEF, Qfalse);
 }
 
+static VALUE
+yield_args_under_i(vinfo)
+    VALUE vinfo;
+{
+    VALUE *info = (VALUE *)vinfo;
+
+    return rb_yield_0(info[0], info[1], ruby_class, YIELD_PUBLIC_DEF, Qtrue);
+}
+
 /* block eval under the class/module context */
 static VALUE
-yield_under(under, self)
-    VALUE under, self;
+yield_under(under, self, args)
+    VALUE under, self, args;
 {
-    return exec_under(yield_under_i, under, 0, self);
+    if (args == Qundef) {
+	return exec_under(yield_under_i, under, 0, self);
+    }
+    else {
+	VALUE info[2] = { args, self };
+
+	return exec_under(yield_args_under_i, under, 0, (VALUE)info);
+    }
 }
 
 static VALUE
@@ -6764,7 +6780,7 @@
 	if (argc > 0) {
 	    rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", argc);
 	}
-	return yield_under(klass, self);
+	return yield_under(klass, self, Qundef);
     }
     else {
 	char *file = "(eval)";
@@ -6836,6 +6852,41 @@
 
 /*
  *  call-seq:
+ *     obj.instance_exec(arg...) {|var...| block }                       => obj
+ *
+ *  Executes the given block within the context of the receiver
+ *  (_obj_). In order to set the context, the variable +self+ is set
+ *  to _obj_ while the code is executing, giving the code access to
+ *  _obj_'s instance variables.  Arguments are passed as block parameters.
+ *
+ *     class KlassWithSecret
+ *       def initialize
+ *         @secret = 99
+ *       end
+ *     end
+ *     k = KlassWithSecret.new
+ *     k.instance_exec(5) {|x| @secret+x }   #=> 104
+ */
+
+VALUE
+rb_obj_instance_exec(argc, argv, self)
+    int argc;
+    VALUE *argv;
+    VALUE self;
+{
+    VALUE klass;
+
+    if (SPECIAL_CONST_P(self)) {
+	klass = Qnil;
+    }
+    else {
+	klass = rb_singleton_class(self);
+    }
+    return yield_under(klass, self, rb_ary_new4(argc, argv));
+}
+
+/*
+ *  call-seq:
  *     mod.class_eval(string [, filename [, lineno]])  => obj
  *     mod.module_eval {|| block }                     => obj
  *  
@@ -8120,6 +8171,7 @@
     rb_define_method(rb_mKernel, "send", rb_f_send, -1);
     rb_define_method(rb_mKernel, "__send__", rb_f_send, -1);
     rb_define_method(rb_mKernel, "instance_eval", rb_obj_instance_eval, -1);
+    rb_define_method(rb_mKernel, "instance_exec", rb_obj_instance_exec, -1);
 
     rb_define_private_method(rb_cModule, "append_features", rb_mod_append_features, 1);
     rb_define_private_method(rb_cModule, "extend_object", rb_mod_extend_object, 1);

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]