From: "tenderlovemaking (Aaron Patterson)" Date: 2013-08-28T03:36:27+09:00 Subject: [ruby-core:56834] [ruby-trunk - Bug #8773] Binding#local_variables should work like #local_variable_set and #local_variable_get Issue #8773 has been updated by tenderlovemaking (Aaron Patterson). @ko1 do you have any thoughts about this? ---------------------------------------- Bug #8773: Binding#local_variables should work like #local_variable_set and #local_variable_get https://bugs.ruby-lang.org/issues/8773#change-41378 Author: jackdanger (Jack Danger) Status: Open Priority: Normal Assignee: Category: core Target version: current: 2.1.0 ruby -v: ruby 2.1.0dev (2013-08-11 trunk 42507) [x86_64-darwin12.4.0] Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN With the addition of Binding#local_variable_get and Binding#local_variable_set the following seemed reasonable: def get_all_local_variables(bind) lvars = bind.send(:local_variables) # `lvars` should equal [:x, :y], but equals [:bind, :lvars] lvars.map {|name| bind.local_variable_get name } end x = 1 y = 2 get_all_local_variables(binding) # NameError: local variable `bind' not defined for # This is because `local_variables' is global and uses the current stack frame. That was not obvious to me. I could have just used binding.eval("local_variables") but that looked very strange when used alongside binding.local_variable_set and binding.local_variable_get. Attached is a patch that gives Binding an instance method that properly lists the local variables defined in the binding. It now works like this: def get_all_local_variables(bind) lvars = bind.local_variables # `lvars` equals [:x, :y] lvars.map {|name| bind.local_variable_get name } end x = 1 y = 2 set_everything_but_x_to_5(binding) # => [1, 1] Here's a GitHub link if you want to see it with colors: https://github.com/JackDanger/ruby/pull/1/files -- http://bugs.ruby-lang.org/