summaryrefslogtreecommitdiff
path: root/proc.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-12-24 16:03:12 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-12-24 16:03:12 +0000
commita11831a9a559c296617559f664bcba0aab254563 (patch)
tree9867a689d68d7cc4befbc7b33e1be16e9529ffe9 /proc.c
parent2e6ffdf9577f2bb6513f2909e9c270d6c9dcd6c0 (diff)
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
Diffstat (limited to 'proc.c')
-rw-r--r--proc.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/proc.c b/proc.c
index 2630df15d0..9de48a053f 100644
--- a/proc.c
+++ b/proc.c
@@ -448,6 +448,58 @@ check_local_id(VALUE bindval, volatile VALUE *pname)
/*
* 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)
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);