Wednesday, August 4, 2010

Bitten by Array#*

Have u tried Array#* ? Its a pretty cool way to return an array, built by concatenating the original array by n times:
1
2
3
4
5
a = [1] * 2
p a # >> [1, 1]

a = %w{a} * 2
p a # >> ["a", "a"]

However, u should be aware that all elements of the new array actually points to the same instance, as proven by their object_id:
1
2
3
4
5
x = 'a'
p x.object_id # >> 70212363949780

a = [x] * 2
p a.map(&:object_id) # >> [70212363949780, 70212363949780]

This means that:
1
2
3
4
5
6
7
8
9
10
11
12
13
# Reassigning one element does not affect another
a = %w{a} * 2
p a.map(&:object_id) # >> [70058328018360, 70058328018360]
a[0] = a[0].sub('a','b')
p a # >> ["b", "a"]
p a.map(&:object_id) # >> [69915340242120, 69915340242360]

# In-place manipulating one element affects another
a = %w{a} * 2
p a.map(&:object_id) # >> [70058328018360, 70058328018360]
a[0].sub!('a','b')
p a # >> ["b", "b"]
p a.map(&:object_id) # >> [70058328018360, 70058328018360]

No comments:

Post a Comment

Labels