mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
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] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@44392 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
2e6ffdf957
commit
a11831a9a5
3 changed files with 70 additions and 0 deletions
|
@ -1,3 +1,9 @@
|
|||
Wed Dec 25 01:03:00 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* 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@ruby-lang.org>
|
||||
|
||||
* test/fileutils/fileasserts.rb (assert_ownership_user): new
|
||||
|
|
53
proc.c
53
proc.c
|
@ -446,6 +446,58 @@ check_local_id(VALUE bindval, volatile VALUE *pname)
|
|||
return lid;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
@ -2718,6 +2770,7 @@ Init_Binding(void)
|
|||
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);
|
||||
|
|
|
@ -83,6 +83,17 @@ class TestVariable < Test::Unit::TestCase
|
|||
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
|
||||
|
|
Loading…
Reference in a new issue