2011-11-20 44 views
2

我试图找出为什么下面的代码不会返回相同的结果:红宝石变量同治问题

CODE 1

p0 = "hello" 
a = [] 
b = p0 
1.upto(5) do |i| 
    b.insert(2,"B") 
    a.push b 
end 

a => ["heBBBBBllo", "heBBBBBllo", "heBBBBBllo", "heBBBBBllo", "heBBBBBllo"] 

CODE 2

p0 = "hello" 
a = [] 
b = p0 
1.upto(5) do |i| 
    b.insert(2,"B") 
    a.push b.inspect 
end 

a => ["\"heBllo\"", "\"heBBllo\"", "\"heBBBllo\"", "\"heBBBBllo\"", "\"heBBBBBllo\""] 

我需要的是代码2的结果,但我不需要像检查方法那样的转义字符。

老实说,我真的不明白为什么检查方法有效,为什么在代码1中没有。 看起来在代码1中,“b”用作指针,并且每次更新时,所有“链接”-b都会更新。

任何线索?

谢谢你提前。

回答

0

好像在代码1,“b”被用作指针,每 时间它的更新,所有的“链接” -b被更新。

正确!在第一种情况下,您将b推入阵列五次,因此结果是a包含五个指向b的指针。在第二种情况下,您推送b.inspect - 这是与b不同的对象。

解决您的第一个例子是调用a.push b.dup相反,它创建的b重复,不会被未来的变化影响到b最简单的方法。

+0

谢谢大家,非常有用,最后我明白了这个难题的缺失部分;)。只是为了好奇:使用b.to_s将会像代码1一样工作。为什么? .to_s方法应该返回一个新的字符串,如.inspect?再次感谢你!!! – r0b0t

3

在代码1中,您正在推送对同一对象的引用。该数组将包含对同一事物的多个引用。

在代码2中,您在不同时刻推送inspect输出。该数组将包含inspect的返回字符串的历史记录。

1
p0 = "hello" 
a = [] 
b = p0 

1.upto(5) do |i| 
    b.insert(2,"B") 
    a.push b.clone 
end 
+1

+1;我忘了提供任何解释之外的东西:/ –

0

'b'是一个字符串,它是一个对象。当你插入一个字母时,它会修改该对象。

在代码1中,同一个对象b被多次推入到数组中,并被多次修改。

但是,b.inspect会返回一个新字符串。因此,在CODE 2中,每次迭代都会将一个新字符串推入数组中,并且该新字符串是“b”查看时间的快照。

您可以使用a.push b.dup来创建b的副本而不更改格式。