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

ruby-changes:2869

From: ko1@a...
Date: 20 Dec 2007 17:20:22 +0900
Subject: [ruby-changes:2869] ko1 - Ruby:r14360 (trunk): * proc.c: support Proc#binding.

ko1	2007-12-20 17:20:02 +0900 (Thu, 20 Dec 2007)

  New Revision: 14360

  Modified files:
    trunk/ChangeLog
    trunk/proc.c
    trunk/sample/test.rb

  Log:
    * proc.c: support Proc#binding.
    * sample/test.rb: add a test.
    


  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/sample/test.rb?r1=14360&r2=14359
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=14360&r2=14359
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/proc.c?r1=14360&r2=14359

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 14359)
+++ ChangeLog	(revision 14360)
@@ -1,3 +1,9 @@
+Thu Dec 20 17:18:38 2007  Koichi Sasada  <ko1@a...>
+
+	* proc.c: support Proc#binding.
+
+	* sample/test.rb: add a test.
+
 Thu Dec 20 17:15:15 2007  Martin Duerst  <duerst@i...>
 
 	* pack.c: Slight change to documentation ('character' ->
Index: sample/test.rb
===================================================================
--- sample/test.rb	(revision 14359)
+++ sample/test.rb	(revision 14360)
@@ -2178,6 +2178,15 @@
 test_ok(File.expand_path(".", "//") == "//")
 test_ok(File.expand_path("sub", "//") == "//sub")
 
+# test_check "Proc#binding"
+ObjectSpace.each_object(Proc){|o|
+  begin
+    b = o.binding
+    eval 'self', b
+  rescue ArgumentError
+  end
+}
+
 test_check "gc"
 begin
   1.upto(10000) {
@@ -2209,6 +2218,7 @@
 ObjectSpace.each_object{|o|
   o.class.name
 }
+
 test_ok true   # reach here or dumps core
 
 if $failed > 0
Index: proc.c
===================================================================
--- proc.c	(revision 14359)
+++ proc.c	(revision 14360)
@@ -1459,7 +1459,41 @@
     return rb_iv_get(exc, "@reason");
 }
 
+/*
+ *  call-seq:
+ *     prc.binding    => binding
+ *  
+ *  Returns the binding associated with <i>prc</i>. Note that
+ *  <code>Kernel#eval</code> accepts either a <code>Proc</code> or a
+ *  <code>Binding</code> object as its second parameter.
+ *     
+ *     def fred(param)
+ *       proc {}
+ *     end
+ *     
+ *     b = fred(99)
+ *     eval("param", b.binding)   #=> 99
+ *     eval("param", b)           #=> 99
+ */
+static VALUE
+proc_binding(VALUE self)
+{
+    rb_proc_t *proc;
+    VALUE bindval = binding_alloc(rb_cBinding);
+    rb_binding_t *bind;
 
+    GetProcPtr(self, proc);
+    GetBindingPtr(bindval, bind);
+
+    if (TYPE(proc->block.iseq) == T_NODE) {
+	rb_raise(rb_eArgError, "Can't create Binding from C level Proc");
+    }
+
+    bind->env = proc->envval;
+    bind->cref_stack = proc->special_cref_stack;
+    return bindval;
+}
+
 /*
  *  <code>Proc</code> objects are blocks of code that have been bound to
  *  a set of local variables. Once bound, the code may be called in
@@ -1497,6 +1531,7 @@
     rb_define_method(rb_cProc, "hash", proc_hash, 0);
     rb_define_method(rb_cProc, "to_s", proc_to_s, 0);
     rb_define_method(rb_cProc, "lambda?", proc_lambda_p, 0);
+    rb_define_method(rb_cProc, "binding", proc_binding, 0);
 
     /* Exceptions */
     rb_eLocalJumpError = rb_define_class("LocalJumpError", rb_eStandardError);

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

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