我试图列出所有局部变量及其值。这适用于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
会根据Thread#stop()
的方法而改变吗?
答案 0 :(得分:2)
您可以将绑定传递给方法。
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
答案 1 :(得分:1)
您的代码非常复杂且混淆。首先,让我们稍微清理一下代码,以便我们能够更清楚地看到正在发生的事情。您不需要self
,因为无论如何它都是默认接收器。而且您不需要send
,因为您已经知道要调用的方法的名称。此外,Kernel#local_variables
无论如何都会使用当前的Binding
。此外,通常情况下,应该通过调用而没有明确的接收者并且实际上不使用self
(例如像puts
或require
)的方法被放入{ {1}}。因此,您的代码等同于以下内容:
Kernel
现在我们可以立即看到问题:您正在思考局部变量和module Kernel
def list_vars
local_variables.map {|var| "#{var} = " + binding.local_variable_get(var).inspect}
end
end
的{{1}}而不是调用它的地方!您需要将Binding
传递给方法并使用它:
list_vars
或者,您可以将其设为Binding
的实例方法:
module Kernel
def list_vars(binding)
binding.local_variables.map {|var| "#{var} = " + binding.local_variable_get(var).inspect}
end
end
list_vars(binding)
答案 2 :(得分:0)
Philip Hallstrom为您提供了一个可用于解决问题的代码,但没有回答您的问题。你问题的真正答案是:是的。