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