为什么在Ruby中需要“ instance_variable_set”?

时间:2018-10-28 02:21:29

标签: ruby

instance_variable_set的意义是什么?这两行不一样吗?

instance_variable_set(@name, value)
@name = value"

5 个答案:

答案 0 :(得分:3)

如果为实例变量分配了“简单”变量,例如:

% initialize adjacency matrix
AM = zeros(198, 198)

% construct adjacency matrix 
L = length(A(1,:));
for i = 1:198
    for j = 1:L
        if AL(i,j) > 0
            AM(i,AL(i,j)) = 1;
        end
    end
end

你做不到

@foo = "foo"

但是您可以对instance_variable_set做类似的事情:

"@#{foo}" = "bar" # syntax error, unexpected '=', expecting end-of-input

根据您的问题这两行不是相同的吗?,例如,它们是相似的,但是人们倾向于不偏向于使用instance_variable_set的用途。

答案 1 :(得分:2)

我想知道为什么没有提到另一个明显的区别:它们具有不同的范围。

@name = value仅可在定义实例变量的范围内访问(从实例内部读取:) instance_variable_set可在任何地方从外部设置实例变量 / em>:

class C
  attr_reader :name
  def initialize(name)
    @name = name
  end
end

C.new("foo").tap do |c|
  c.instance_variable_set(:@name, 42)
  c.name
end
#⇒ 42

答案 2 :(得分:1)

来自fine manual

  

instance_variable_set(symbol,obj)→obj
   instance_variable_set(string,obj)→obj

     

[a b c d e f] -> [a [b c d] e f] 命名的实例变量设置为给定的对象,从而使类的作者尝试提供适当的封装的工作变得沮丧。该变量在此调用之前不必存在。如果实例变量名称作为字符串传递,则该字符串将转换为符号。

第一个参数不是symbol,而是@name(即符号)或:@name(字符串)。

结果是,如文档中所述,'@name'可以在您知道实例名称的情况下用于设置实例变量,即使您在运行代码之前都不知道实例名称。

答案 3 :(得分:1)

这里是一个示例,说明如何使用方法Object#instance_variable_setObject#instance_variable_get将所有实例变量的值加1。

class Klass
  attr_accessor :a, :b, :cat
  def initialize
    @a, @b, @c, @d = 1, 2, 3, 4
  end
end

k = Klass.new
  #=> #<Klass:0x0000000001d70978 @a=1, @b=2, @c=3, @cat=4>
k.instance_variables.each { |v| k.instance_variable_set(v, k.instance_variable_get(v)+1) }
  #=> [:@a, :@b, :@c, :@cat]
k #=> #<Klass:0x0000000001d70978 @a=2, @b=3, @c=4, @cat=5>

另请参阅Object#instance_variables

与具有四个单独的赋值语句相比,所需的代码行更少,但是还有另外两个更重要的优点:

  • 引入错误(k.cut += 1)的机会较小;和
  • 添加,删除或重命名实例变量不需要更改值递增代码。

此方法的一种变体是用动态构造的实例变量名称数组(例如[:@a, :@b])替换上面的instance_variables

这些似乎是不寻常的示例,但是它们代表了涉及实例变量的一大类操作,在这些操作中,可以使用这种批处理方法加以利用。

答案 4 :(得分:1)

  

我是Ruby的新手,在阅读一些教程时遇到了这个问题。我很好奇Object#instance_variable_set的意义是什么?

instance_variable_set(@name, value) @name = value 的重点是动态地反射性地设置一个实例变量,该变量的名称在设计时可能只有在运行时才知道。

  

这两行不一样吗?

@name

不,这些行完全不同,它们完美地说明了我在上面写的内容:

  • 第一行将实例名称​​存储在value 中的实例变量设置为@name
  • 第二行将实例变量value设置为{{1}}。