获取给定实例变量名称的实例变量的值

时间:2020-12-06 23:39:12

In general, how can I get a reference to an object whose name I have in a string?

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

More specifically, I have a list of the parameter names (the member variables - built dynamically so I can't refer to them directly).

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

Each parameter is an object that also has an from_s method.

每个参数都是具有from_s方法的对象。

I want to do something like the following (which of course doesn't work...):

我想做如下的事情(这当然行不通…):

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

2 个解决方案

#1


158  

The most idiomatic way to achieve this is:

实现这一点的最惯用的方法是:

some_object.instance_variable_get("@#{name}")

There is no need to use + or intern; Ruby will handle this just fine. However, if you find yourself reaching into another object and pulling out its ivar, there's a reasonably good chance that you have broken encapsulation.

无需使用+或实习生;Ruby可以很好地处理这个问题。然而,如果您发现自己进入了另一个对象并拔出了它的ivar,那么您很有可能已经破坏了封装。

If you explicitly want to access an ivar, the right thing to do is to make it an accessor. Consider the following:

如果显式地希望访问ivar,正确的做法是使其成为访问器。考虑以下:

class Computer
  def new(cpus)
    @cpus = cpus
  end
end

In this case, if you did Computer.new, you would be forced to use instance_variable_get to get at @cpus. But if you're doing this, you probably mean for @cpus to be public. What you should do is:

如果你用电脑的话。新的,您将*使用instance_variable_get来获取@cpus。但是如果您这样做,您可能是指@cpus是公开的。你应该做的是:

class Computer
  attr_reader :cpus
end

Now you can do Computer.new(4).cpus.

现在你可以做电脑了。新的(4).cpu。

Note that you can reopen any existing class and make a private ivar into a reader. Since an accessor is just a method, you can do Computer.new(4).send(var_that_evaluates_to_cpus)

注意,您可以重新打开任何现有的类,并将一个私有的ivar变成一个阅读器。由于访问器只是一个方法,您可以执行Computer.new(4).send(var_that_evaluates_to_cpus)

#2


7  

To get an instance variable from the name of an instance variable do:

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

name = "paramName"
instance_variable_get(("@" + name).intern)

This will return the value of the instance variable @paramName

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

#1


158  

The most idiomatic way to achieve this is:

实现这一点的最惯用的方法是:

some_object.instance_variable_get("@#{name}")

There is no need to use + or intern; Ruby will handle this just fine. However, if you find yourself reaching into another object and pulling out its ivar, there's a reasonably good chance that you have broken encapsulation.

无需使用+或实习生;Ruby可以很好地处理这个问题。然而,如果您发现自己进入了另一个对象并拔出了它的ivar,那么您很有可能已经破坏了封装。

If you explicitly want to access an ivar, the right thing to do is to make it an accessor. Consider the following:

如果显式地希望访问ivar,正确的做法是使其成为访问器。考虑以下:

class Computer
  def new(cpus)
    @cpus = cpus
  end
end

In this case, if you did Computer.new, you would be forced to use instance_variable_get to get at @cpus. But if you're doing this, you probably mean for @cpus to be public. What you should do is:

如果你用电脑的话。新的,您将*使用instance_variable_get来获取@cpus。但是如果您这样做,您可能是指@cpus是公开的。你应该做的是:

class Computer
  attr_reader :cpus
end

Now you can do Computer.new(4).cpus.

现在你可以做电脑了。新的(4).cpu。

Note that you can reopen any existing class and make a private ivar into a reader. Since an accessor is just a method, you can do Computer.new(4).send(var_that_evaluates_to_cpus)

注意,您可以重新打开任何现有的类,并将一个私有的ivar变成一个阅读器。由于访问器只是一个方法,您可以执行Computer.new(4).send(var_that_evaluates_to_cpus)

#2


7  

To get an instance variable from the name of an instance variable do:

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

name = "paramName"
instance_variable_get(("@" + name).intern)

This will return the value of the instance variable @paramName

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