Skip to content

Commit

Permalink
* proc.c: support Proc#binding.
Browse files Browse the repository at this point in the history
* sample/test.rb: add a test.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@14360 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information
ko1 committed Dec 20, 2007
1 parent 1b79b5b commit 40d8543
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 0 deletions.
6 changes: 6 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Thu Dec 20 17:18:38 2007 Koichi Sasada <ko1@atdot.net>

* proc.c: support Proc#binding.

* sample/test.rb: add a test.

Thu Dec 20 17:15:15 2007 Martin Duerst <duerst@it.aoyama.ac.jp>

* pack.c: Slight change to documentation ('character' ->
Expand Down
35 changes: 35 additions & 0 deletions proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1459,6 +1459,40 @@ localjump_reason(VALUE exc)
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
Expand Down Expand Up @@ -1497,6 +1531,7 @@ Init_Proc(void)
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);
Expand Down
10 changes: 10 additions & 0 deletions sample/test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2178,6 +2178,15 @@ def quux
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) {
Expand Down Expand Up @@ -2209,6 +2218,7 @@ def initialize(a)
ObjectSpace.each_object{|o|
o.class.name
}

test_ok true # reach here or dumps core

if $failed > 0
Expand Down

0 comments on commit 40d8543

Please sign in to comment.