10000 proc.c: Binding#local_variables · eagletmt/ruby@a11831a · GitHub
[go: up one dir, main page]

Skip to content

Commit a11831a

Browse files
committed
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 ruby#8773] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@44392 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
1 parent 2e6ffdf commit a11831a

File tree

3 files changed

+70
-0
lines changed

3 files changed

+70
-0
lines changed

ChangeLog

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
Wed Dec 25 01:03:00 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
2+
3+
* proc.c (bind_local_variables): allowing binding to list its
4+
local variables. patch by Jack Danger Canty <jackdanger AT
5+
squareup.com> at [ruby-core:56543]. [Feature #8773]
6+
17
Tue Dec 24 23:20:38 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
28

39
* test/fileutils/fileasserts.rb (assert_ownership_user): new

proc.c

Lines changed: 53 additions & 0 deletions
8000
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,58 @@ check_local_id(VALUE bindval, volatile VALUE *pname)
446446
return lid;
447447
}
448448

449+
/*
450+
* call-seq:
451+
* binding.local_variables -> Array
452+
*
453+
* Returns the +symbol+ names of the binding's local variables
454+
*
455+
* def foo
456+
* a = 1
457+
* 2.times do |n|
458+
* binding.local_variables #=> [:a, :n]
459+
* end
460+
* end
461+
*
462+
* This method is short version of the following code.
463+
*
464+
* binding.eval("local_variables")
465+
*
466+
*/
467+
static VALUE
468+
bind_local_variables(VALUE bindval)
469+
{
470+
VALUE ary = rb_ary_new();
471+
472+
const rb_binding_t *bind;
473+
const rb_env_t *env;
474+
VALUE envval;
475+
476+
GetBindingPtr(bindval, bind);
477+
478+
envval = bind->env;
479+
GetEnvPtr(envval, env);
480+
481+
do {
482+
const rb_iseq_t *iseq;
483+
int i;
484+
ID id;
485+
iseq = env->block.iseq;
486+
487+
for (i = 0; i < iseq->local_table_size; i++) {
488+
id = iseq->local_table[i];
489+
if (id) {
490+
const char *vname = rb_id2name(id);
491+
if (vname) {
492+
rb_ary_push(ary, ID2SYM(id));
493+
}
494+
}
495+
}
496+
} while ((envval = env->prev_envval) != 0);
497+
498+
return ary;
499+
}
500+
449501
/*
450502
* call-seq:
451503
* binding.local_variable_get(symbol) -> obj
@@ -2718,6 +2770,7 @@ Init_Binding(void)
27182770
rb_define_method(rb_cBinding, "clone", binding_clone, 0);
27192771
rb_define_method(rb_cBinding, "dup", binding_dup, 0);
27202772
rb_define_method(rb_cBinding, "eval", bind_eval, -1);
2773+
rb_define_method(rb_cBinding, "local_variables", bind_local_variables, 0);
27212774
rb_define_method(rb_cBinding, "local_variable_get", bind_local_variable_get, 1);
27222775
rb_define_method(rb_cBinding, "local_variable_set", bind_local_variable_set, 2);
27232776
rb_define_method(rb_cBinding, "local_variable_defined?", bind_local_variable_defined_p, 1);

test/ruby/test_variable.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,17 @@ def test_local_variables3
8383
end.call
8484
end
8585

86+
def local_variables_of(bind)
87+
this_should_not_be_in_bind = 2
88+
bind.local_variables
89+
end
90+
91+
def test_local_variables_from_other_method_binding
92+
feature8773 = '[Feature #8773]'
93+
x = 1
94+
assert_equal([:x], local_variables_of(binding), feature8773)
95+
end
96+
8697
def test_global_variable_0
8798
assert_in_out_err(["-e", "$0='t'*1000;print $0"], "", /\At+\z/, [])
8899
end

0 commit comments

Comments
 (0)
0