在irb中列出局部变量

时间:2015-08-12 22:32:57

标签: ruby irb local-variables

我试图列出所有局部变量及其值。这适用于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()的方法而改变吗?

3 个答案:

答案 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(例如像putsrequire)的方法被放入{ {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为您提供了一个可用于解决问题的代码,但没有回答您的问题。你问题的真正答案是:是的。