列出 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(例如像 putsrequire)被放入 Kernel.因此,您的代码等效于以下内容:

module Kernel
  def list_vars
    local_variables.map {|var| "#{var} = " + binding.local_variable_get(var).inspect}
  end
end

现在我们可以立即看到问题所在:您反映的是局部变量和 list_varsBinding 而不是调用它的地方!您需要将 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