Project

General

Profile

Feature #8773 » 0001-Allowing-binding-to-list-its-local-variables.patch

Create Binding#local_variables - jackdanger (Jack Danger), 08/11/2013 03:21 PM

View differences:

proc.c
/*
* 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+.
......
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);
test/ruby/test_variable.rb
end.call
end
def _new_binding(bind)
this_should_not_be_in_bind = 2
assert_equal([:x], bind.local_variables)
end
def test_local_variables_from_other_method_binding
x = 1
_new_binding(binding)
end
def test_global_variable_0
assert_in_out_err(["-e", "$0='t'*1000;print $0"], "", /\At+\z/, [])
end
(1-1/2)