Ruby变量管理问题

时间:2011-11-20 23:40:28

标签: ruby variables pointers

我试图弄清楚为什么以下代码不会返回相同的结果:

代码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"]

代码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\""]

我需要的是Code 2的结果,但我不需要像inspect方法那样的转义字符。

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

任何线索??

提前谢谢。

4 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

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

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

但是,b.inspect返回一个新字符串。所以在CODE 2中,每次迭代都会将一个新字符串推送到数组中,而新字符串是“b”在时间上看的快照。

你可以改用a.push b.dup,它可以在不改变格式的情况下创建b的副本。

答案 3 :(得分:0)

  

似乎在代码1中,“b”用作指针,并且每次都使用   它已更新,所有“链接”-b都会更新。

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

修复第一个示例的最简单方法是改为调用a.push b.dup,这会创建b的副本,不会受到b的未来更改的影响。