2013-09-28 105 views
0

當我有下面的方法:紅寶石參考

def n_times(thing) 
    lambda { |n| thing * n } 
end 

和我把它這樣:

x = [:a] 
p1 = n_times(x) 
x = [:b] 
p p1.call(3) # => [:a, :a, :a] 

x將不被改變,輸出將是[:A]。爲什麼?

在做這樣的事情.pop實際上,X將被改變:

x = [:a] 
p1 = n_times(x) 
x.pop 
p p1.call(3) # => [] 

是因爲[:B]是一個新的對象?

回答

1

這是因爲x在第一種情況下被分配了一個新對象。您可以通過檢查object_id

x = [:a] 
p x.object_id # => //some number 
p1 = n_times(x) 
x = [:b] 
p x.object_id # => //diff number 
p p1.call(3) # => [:a, :a, :a] 

x = [:a] 
p x.object_id # => //some number 
p1 = n_times(x) 
x.pop 
p x.object_id # => //same number 
p p1.call(3) # => [] 

# Another example 
x = [:a] 
p x.object_id # => //some number 
p1 = n_times(x) 
x[0] = :b 
p x.object_id # => //same number 
p p1.call(3) # => [:b, :b, :b] 
1

是因爲[:b]是新對象嗎?

是的。當你做x.pop時,你正在修改xthing所引用的對象。當你做x = [:b]時,你讓x引用一個新的對象。創建變量引用新對象不會影響其他變量或對象。

請注意,如果lambda關閉了變量x,這將是另一回事。在這種情況下,更改x會影響lambda,但事實並非如此。 lambda關閉變量thing,這是一個不同的變量,它只是在重新分配x之前碰巧指向同一個對象。