我知道ObjectSpance得到的字符串如下:
strings = ObjectSpace.each_object(String);但它并不全是ruby中的字符串;如果我想得到一个像这样的local_variables:
module My
def self.test
a = "I'm a string"
end
end为了得到"I'm a string",ObjectSpace能做到吗?“
发布于 2018-02-16 12:29:12
在定义字符串的范围内,字符串“不知道”哪些局部变量(如果有的话)保存了它们的值。也就是说,该信息不能仅从字符串中获得。例如,对于a=['cat', 'dog'],'cat'和'dog'由无局部变量持有,而在a = b = 'cat'中,'cat'由两个局部变量持有。而且,两个相同的(未冻结的)字符串是不同的对象。因此,即使我们可以以某种方式使用ObjectSpace.each_obect(String)以某种方式深入到所有类实例的方法中(我们不能),我们也无法检索到所需的信息。
我们也不能识别方法中的局部变量,然后确定它们的值。这是因为它们可能存在的唯一时间是在方法被调用之后和返回之前,而这些信息在方法之外是不可用的。此外,它可能会在方法的执行过程中发生变化。
在任何时间点,都可以获得局部变量及其值(但只能从方法中获得),如下所示。
def at
b = 3
c = 4
local_variables.map { |v| [v, binding.local_variable_get(v)] }.to_h
end
at
#=> {:b=>3, :c=>4}然而,这无助于回答操作员的问题。
情况有点不同,因为我们被要求在给定的时间点识别每个现有类的每个现有实例的所有实例变量及其值(这样我们就可以将注意力集中在包含字符串的实例变量上)。
例如,假设我们定义了以下类。
class Z
def initialize(str1, str2)
@z1, @z2 = str1, str2
end
end并创建此类的两个实例。
mimi_fufu = Z.new 'mimi', 'fufu'
#=> #<Z:0x00000001269160 @z1="mimi", @z2="fufu">
fido_biff = Z.new 'fido', 'biff'
#=> #<Z:0x000000012772b0 @z1="fido", @z2="biff">现在,ObjectSpace.each_object(Class)返回当前定义的所有类的数组,其中一个是Z,ObjectSpace.each_object(Z)返回Z的所有实例的数组。因此,我们可以执行以下计算来获得Z所需的信息(因此,对于每个其他现有的类)。
ObjectSpace.each_object(Z).map do |inst|
{ instance: inst,
inst_vars: inst.instance_variables.each_with_object({}) { |iv,h|
h[iv] = inst.instance_variable_get(iv) } }
end
#=> [{:instance=>#<Z:0x00000001269160 @z1="mimi", @z2="fufu">,
# :inst_vars=>{:@z1=>"mimi", :@z2=>"fufu"}},
# {:instance=>#<Z:0x000000012772b0 @z1="fido", @z2="biff">,
# :inst_vars=>{:@z1=>"fido", :@z2=>"biff"}}]https://stackoverflow.com/questions/48819204
复制相似问题