列出 irb 中的局部变量
listing the local variables in irb
我正在尝试列出所有局部变量及其值。这在 IRB 中有效:
local_variables.map {|var| "#{var} = " + local_variable_get(var).inspect
我想将它包装在一个方法中,但是当这段代码放在一个方法中时,local_variables
不再指向正确的变量列表。因此,我尝试了一些解决方案:
class Object
def list_vars
self.__send__(:binding).local_variables.map {|var| "#{var} = " + self.__send__(:binding).local_variable_get(var).inspect}
end
end
不过好像当前对象的绑定和main
不一样,是直接调用local_variables
的时候用的
self.send(:binding)
会根据 self
所在的方法而改变吗?
您可以将绑定传递给方法。
class Object
def list_vars(b)
a = 1 # This is only here to demonstrate. It's not necessary for it to work.
b.local_variables.each do |var|
puts "#{var} = " + b.local_variable_get(var).inspect
end
end
end
x = 1
list_vars(binding)
def foo
z = 1
list_vars(binding)
end
foo
将输出:
x = 1
z = 1
Philip Hallstrom 为您提供了可用于解决问题的代码,但并未回答您的问题。你的问题的真正答案是:是的。
你的代码真的很复杂和混淆。首先,让我们稍微清理一下您的代码,以便我们可以更清楚地看到发生了什么。您不需要 self
,因为无论如何它都是默认接收器。而你不需要send
,因为你已经知道你要调用的方法的名字了。此外,Kernel#local_variables
仍然使用当前的 Binding
。此外,通常,这些方法应该在没有显式接收者的情况下被调用并且实际上不使用 self
(例如像 puts
或 require
)被放入 Kernel
.因此,您的代码等效于以下内容:
module Kernel
def list_vars
local_variables.map {|var| "#{var} = " + binding.local_variable_get(var).inspect}
end
end
现在我们可以立即看到问题所在:您反映的是局部变量和 list_vars
的 Binding
而不是调用它的地方!您需要将 Binding
传递到方法中并改用它:
module Kernel
def list_vars(binding)
binding.local_variables.map {|var| "#{var} = " + binding.local_variable_get(var).inspect}
end
end
list_vars(binding)
或者,您可以将其设为 Binding
:
的实例方法
class Binding
def list_vars
local_variables.map {|var| "#{var} = " + local_variable_get(var).inspect}
end
end
binding.list_vars
我正在尝试列出所有局部变量及其值。这在 IRB 中有效:
local_variables.map {|var| "#{var} = " + local_variable_get(var).inspect
我想将它包装在一个方法中,但是当这段代码放在一个方法中时,local_variables
不再指向正确的变量列表。因此,我尝试了一些解决方案:
class Object
def list_vars
self.__send__(:binding).local_variables.map {|var| "#{var} = " + self.__send__(:binding).local_variable_get(var).inspect}
end
end
不过好像当前对象的绑定和main
不一样,是直接调用local_variables
的时候用的
self.send(:binding)
会根据 self
所在的方法而改变吗?
您可以将绑定传递给方法。
class Object
def list_vars(b)
a = 1 # This is only here to demonstrate. It's not necessary for it to work.
b.local_variables.each do |var|
puts "#{var} = " + b.local_variable_get(var).inspect
end
end
end
x = 1
list_vars(binding)
def foo
z = 1
list_vars(binding)
end
foo
将输出:
x = 1
z = 1
Philip Hallstrom 为您提供了可用于解决问题的代码,但并未回答您的问题。你的问题的真正答案是:是的。
你的代码真的很复杂和混淆。首先,让我们稍微清理一下您的代码,以便我们可以更清楚地看到发生了什么。您不需要 self
,因为无论如何它都是默认接收器。而你不需要send
,因为你已经知道你要调用的方法的名字了。此外,Kernel#local_variables
仍然使用当前的 Binding
。此外,通常,这些方法应该在没有显式接收者的情况下被调用并且实际上不使用 self
(例如像 puts
或 require
)被放入 Kernel
.因此,您的代码等效于以下内容:
module Kernel
def list_vars
local_variables.map {|var| "#{var} = " + binding.local_variable_get(var).inspect}
end
end
现在我们可以立即看到问题所在:您反映的是局部变量和 list_vars
的 Binding
而不是调用它的地方!您需要将 Binding
传递到方法中并改用它:
module Kernel
def list_vars(binding)
binding.local_variables.map {|var| "#{var} = " + binding.local_variable_get(var).inspect}
end
end
list_vars(binding)
或者,您可以将其设为 Binding
:
class Binding
def list_vars
local_variables.map {|var| "#{var} = " + local_variable_get(var).inspect}
end
end
binding.list_vars