Hello there Ruby-minded people!
I am writing because I am somewhat stumped by why the following
discrepency occurs; having defined the following:
class Warfare
def haves
x = [1]
y = []
y << x
x = [2] # (compare this)
y
end
def havenots
x = [1]
y = []
y << x
x[0] = 2 # (to this)
y
end
end
I get this in irb:
load ‘snah.rb’
=> true
a = Warfare.new
=> #Warfare:0x33a93c
a.haves
=> [[1]]
a.havenots
=> [[2]]
Why does meddling with the innards of the “x” have retroactive
repercussions, whereas redefining it outright does not?
Any insight would be greatly appreciated.
-Jonah
On Tue, Aug 19, 2008 at 4:16 PM, Jonah Bloch-Johnson
[email protected] wrote:
repercussions, whereas redefining it outright does not?
When you say ‘x = [2]’ you aren’t redefining the object x, you are
taking the variable ‘x’ and binding it to a new object. When you say y
<< x, you are inserting the object that x was pointing to at that
moment into y, not the variable x. Think of a variable as an alias for
an object - what is actually passed around are the objects themselves,
but you can refer to them by any of their current aliases.
martin
Many many many thanks, Adam and Martin! I do think this clears it up.
Quoting A. Shelly [email protected]:
On 8/19/08, Jonah Bloch-Johnson [email protected] wrote:
I am writing because I am somewhat stumped by why the following discrepency occurs…
Variables and Array entries hold references to objects.
irb(main):001:0> x=[1]
=> [1]
irb(main):002:0> x.object_id
=> 20774910
irb(main):003:0> y=[];y<<x
=> [[1]]
irb(main):004:0> y[0].object_id
=> 20774910 #the same object that x referrs to
irb(main):005:0> x=[2]
=> [2]
irb(main):006:0> x.object_id
=> 21222360 #now x refers to the newly created array
irb(main):008:0> y
=> [[1]]
irb(main):007:0> y[0].object_id
=> 20774910 #but y still holds a reference to the old one.
irb(main):009:0> y=[x]
=> [[2]]
irb(main):010:0> y[0].object_id
=> 21222360 #y[0] is now a reference to the same Array as x
irb(main):011:0> x[0]=4
=> 4
irb(main):013:0> y
=> [[4]] #so changes to the content of that Array are visible
through y’s reference.
hope this helps,
-Adam
x = [1]
[1] is an Array object, x is a variable referring to that array
y = []
y referrs to a 2nd Array
y << x
And now that array contains a reference to
x = [2] # (compare this)
Here you are creating an array, labeling it ‘x’, and storing a
reference to it in the array labeled y. Then you reassign the ‘x’
label to yet another array (the one containing 2).