From: ale@...
Date: 2001-09-01T18:37:16+09:00
Subject: [ruby-talk:20661] Re: replacing items in arrays
Hello Tobias,
On Sat, 1 Sep 2001, Tobias Reif wrote:
> 1.
> why doesn't the second block work?
>
> line[line_index] = '
' + line[line_index] + ' | '
vs.
> item = line[line_index]
> item = '' + item + ' | '
Well, the reason is the same as with:
ruby -e'a=[1,2,3]; b = a[1]; b = 4; p a; a[1] = 4; p a;'
[1, 2, 3]
[1, 4, 3]
The objects for the above are ('->' is a notation for a reference):
a -> [-> 1,
-> 2,
-> 3
]
Statement b = a[1];
b -> 2 (b starts to refer the Fixnum object with content 2
and the object is exactly the same as the one
a[1] is referring to)
statement b = 4;
b -> 4
And when you print array a, it's still an array with element 0 referring
to an Fixnum object of 1, element 1 referring to a Fixnum object of 2, and
likewise for element 2.
Statement a[1] = 4 alters the array to be
a -> [-> 1,
-> 4,
-> 3
]
The first block version first generates a value by
'' + a[2] + ' | '
and then says a[2] = new_value, where as the latter block version never
alters a[2], thus the table remains the same.
Beware there's always danger when you use exclamation-methods,
a=["a", "b", "c"];
b = a[1]
b.gsub(/b/, "bb")
p a
b = a[1]
b.gsub!(/b/, "bb")
p a
=>
["a", "b", "c"]
["a", "bb", "c"]
and one has to be careful even with non-exclamated ones if they clearly
alter the state of an object:
a = ["a", "b", "c"]
b = a[1]
b += "b"
p a
b = a[1]
b.concat "b"
p a
> 2.
> wouldn't it be nice to be able to just say:
>
> Array#replace_each:
> -----
> an_array = ['one', 'two']
>
> an_array.replace_each do |item|
> 'number ' + item
> end
> -----
> -> ['number one', 'number two']
>
> Or did I overlook an equivalent?
a = ["one", "two"]
a.collect! { |e| "number " + e }
p a
=>
["number one", "number two"]
- Aleksi