ruby-changes:32313
From: nobu <ko1@a...>
Date: Wed, 25 Dec 2013 01:03:17 +0900 (JST)
Subject: [ruby-changes:32313] nobu:r44392 (trunk): proc.c: Binding#local_variables
nobu 2013-12-25 01:03:12 +0900 (Wed, 25 Dec 2013) New Revision: 44392 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=44392 Log: proc.c: Binding#local_variables * proc.c (bind_local_variables): allowing binding to list its local variables. patch by Jack Danger Canty <jackdanger AT squareup.com> at [ruby-core:56543]. [Feature #8773] Modified files: trunk/ChangeLog trunk/proc.c trunk/test/ruby/test_variable.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 44391) +++ ChangeLog (revision 44392) @@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Wed Dec 25 01:03:00 2013 Nobuyoshi Nakada <nobu@r...> + + * proc.c (bind_local_variables): allowing binding to list its + local variables. patch by Jack Danger Canty <jackdanger AT + squareup.com> at [ruby-core:56543]. [Feature #8773] + Tue Dec 24 23:20:38 2013 Nobuyoshi Nakada <nobu@r...> * test/fileutils/fileasserts.rb (assert_ownership_user): new Index: proc.c =================================================================== --- proc.c (revision 44391) +++ proc.c (revision 44392) @@ -448,6 +448,58 @@ check_local_id(VALUE bindval, volatile V https://github.com/ruby/ruby/blob/trunk/proc.c#L448 /* * call-seq: + * binding.local_variables -> Array + * + * Returns the +symbol+ names of the binding's local variables + * + * def foo + * a = 1 + * 2.times do |n| + * binding.local_variables #=> [:a, :n] + * end + * end + * + * This method is short version of the following code. + * + * binding.eval("local_variables") + * + */ +static VALUE +bind_local_variables(VALUE bindval) +{ + VALUE ary = rb_ary_new(); + + const rb_binding_t *bind; + const rb_env_t *env; + VALUE envval; + + GetBindingPtr(bindval, bind); + + envval = bind->env; + GetEnvPtr(envval, env); + + do { + const rb_iseq_t *iseq; + int i; + ID id; + iseq = env->block.iseq; + + for (i = 0; i < iseq->local_table_size; i++) { + id = iseq->local_table[i]; + if (id) { + const char *vname = rb_id2name(id); + if (vname) { + rb_ary_push(ary, ID2SYM(id)); + } + } + } + } while ((envval = env->prev_envval) != 0); + + return ary; +} + +/* + * call-seq: * binding.local_variable_get(symbol) -> obj * * Returns a +value+ of local variable +symbol+. @@ -2718,6 +2770,7 @@ Init_Binding(void) https://github.com/ruby/ruby/blob/trunk/proc.c#L2770 rb_define_method(rb_cBinding, "clone", binding_clone, 0); rb_define_method(rb_cBinding, "dup", binding_dup, 0); rb_define_method(rb_cBinding, "eval", bind_eval, -1); + rb_define_method(rb_cBinding, "local_variables", bind_local_variables, 0); rb_define_method(rb_cBinding, "local_variable_get", bind_local_variable_get, 1); rb_define_method(rb_cBinding, "local_variable_set", bind_local_variable_set, 2); rb_define_method(rb_cBinding, "local_variable_defined?", bind_local_variable_defined_p, 1); Index: test/ruby/test_variable.rb =================================================================== --- test/ruby/test_variable.rb (revision 44391) +++ test/ruby/test_variable.rb (revision 44392) @@ -83,6 +83,17 @@ class TestVariable < Test::Unit::TestCas https://github.com/ruby/ruby/blob/trunk/test/ruby/test_variable.rb#L83 end.call end + def local_variables_of(bind) + this_should_not_be_in_bind = 2 + bind.local_variables + end + + def test_local_variables_from_other_method_binding + feature8773 = '[Feature #8773]' + x = 1 + assert_equal([:x], local_variables_of(binding), feature8773) + end + def test_global_variable_0 assert_in_out_err(["-e", "$0='t'*1000;print $0"], "", /\At+\z/, []) end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/