根据名称获取实例变量的值

LK_*_*K__ 94 ruby metaprogramming

一般来说,如何获取对字符串中名称的对象的引用?

更具体地说,我有一个参数名称列表(成员变量 - 动态构建,所以我不能直接引用它们).

每个参数都是一个也有from_s方法的对象.

我想做类似以下的事情(当然这不起作用......):

define_method(:from_s) do | arg |
    @ordered_parameter_names.each do | param |
        instance_eval "field_ref = @#{param}"
        field_ref.from_s(param)
    end
end
Run Code Online (Sandbox Code Playgroud)

Yeh*_*atz 173

实现这一目标最常用的方法是:

some_object.instance_variable_get("@#{name}")
Run Code Online (Sandbox Code Playgroud)

没有必要使用+intern; Ruby会处理这个问题.但是,如果你发现自己正在接触到另一个物体并拔出它的ivar,那么你有很好的机会破坏封装.

如果您明确要访问ivar,正确的做法是使其成为访问者.考虑以下:

class Computer
  def new(cpus)
    @cpus = cpus
  end
end
Run Code Online (Sandbox Code Playgroud)

在这种情况下,如果你这样做Computer.new,你将被迫使用instance_variable_get来获取@cpus.但如果你这样做,你可能意味着@cpus公开.你应该做的是:

class Computer
  attr_reader :cpus
end
Run Code Online (Sandbox Code Playgroud)

现在你可以做到Computer.new(4).cpus.

请注意,您可以重新打开任何现有类,并将私有ivar创建到读者中.由于访问器只是一种方法,您可以这样做Computer.new(4).send(var_that_evaluates_to_cpus)


Dan*_*aft 9

要从实例变量的名称获取实例变量,请执行以下操作:

name = "paramName"
instance_variable_get(("@" + name).intern)
Run Code Online (Sandbox Code Playgroud)

这将返回实例变量的值 @paramName

  • 此外,这与反序列化无关.更好的标题可能是"获取给定名称的实例变量的值"或其他内容. (2认同)