Its basically like (probably IS under the hood) Pointers.
so for some arrays a and b
a = b
thats basically copying the pointers themselves. So whatever changes i
make in A will be reflected in B.
Roughly. The Array itself exists on the heap independently of a and b; a
b are local variables, basically just slots in the stack which contain a
reference to the Array.
The difference is that local variables themselves are not objects, and
cannot take a “reference” to a or b.
So whereas in C you could write
void *p = malloc(50);
void *q = p; # q is a another pointer to the malloc space
void **r = &p; # r points to the pointer p <<<< NOTE
in Ruby you can only do
p = “x” * 50
q = p
This actually makes life simpler. If you call
then the method foo can mutate the object p, but on return p will
be unchanged, i.e. is a reference to the same object. You cannot change
p references, unless you explicitly return a new object, e.g.
p = foo§
Of course, the biggest simplification over C is garbage collection. The
Array will be garbage collected once nothing else contains a reference
(either a local variable or another live object)
a = b.dup
create some NEW pointers but which point to the same memory space.
No. It allocates new memory space and copies the contents of the space
referenced by ‘a’ into the new space.
However, that space may in turn contain pointers (references) to other
memory spaces (objects). Since this is a direct copy, the new object
contains the same references as the old object.
obj1 = “foo”
obj2 = “bar”
a = [obj1, obj2] # a points to an Array which contains
b = a.dup # b points to a different Array which
# &obj1, &obj2
In the latter case you could have written b = [a, a], or
b = [obj1, obj2], and got the same result: a new array, which contains
same pointers as the old array.
You can modify the array referenced by b - e.g. by adding or replacing
element - and this won’t affect the other array referenced by a. But if
follow b to find obj1, and modify obj1, then obj1 is changed.
Subsequently accessing the object referred to by a or b will find
same changed obj1.
Use the “object_id” method to see if you’re pointing to the same “memory
irb(main):001:0> a = [“abc”,“def”]
=> [“abc”, “def”]
irb(main):003:0> b = a.dup
=> [“abc”, “def”]
You can think of object_id as a kind of encoded pointer.