# Bug or not a bug? array\*=int

**URL:** <https://www.ruby-forum.com/t/bug-or-not-a-bug-array-int/152059>\
**Category:** Ruby\
**Created:** [October 29, 2008, 4:31pm UTC](https://www.ruby-forum.com/t/bug-or-not-a-bug-array-int/152059 "2008-10-29T16:31:35Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![kyle\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f6c823/32.png) [@kyle\_s](https://www.ruby-forum.com/u/kyle_s)\
**Post date:** [October 29, 2008, 4:31pm UTC](https://www.ruby-forum.com/t/bug-or-not-a-bug-array-int/152059/1 "2008-10-29T16:31:35Z")

</div>

So I’m wondering, is this a bug, or not a bug, or a type-o in the docs?

According to [class Array - RDoc Documentation](http://www.ruby-doc.org/core/classes/Array.html)  
array\*int “[R]eturns a new array built by concatenating the int  
copies of self.”  
Copies should be brand new independent copies, right?

foo=[[nil,nil,nil]]returns a new array built by concatenating the int  
copies of self.  
foo\*=3  
#Foo is now.  
#[[nil,nil,nil],

# [nil,nil,nil],

# [nil,nil,nil]]

foo[1][1]=12  
#Foo is now  
#[[nil,12,nil],

# [nil,12,nil],

# [nil,12,nil]]

#But I would have expected it to be  
#[[nil,nil,nil],

# [nil,12,nil],

# [nil,nil,nil]]

---

<div class="post-metadata">

**Author:** ![kyle\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f6c823/32.png) [@kyle\_s](https://www.ruby-forum.com/u/kyle_s)\
**Post date:** [October 29, 2008, 5:13pm UTC](https://www.ruby-forum.com/t/bug-or-not-a-bug-array-int/152059/2 "2008-10-29T17:13:54Z")

</div>

On Wed, Oct 29, 2008 at 8:30 AM, Kyle S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> So I’m wondering, is this a bug, or not a bug, or a type-o in the docs?
> 
> According to [class Array - RDoc Documentation](http://www.ruby-doc.org/core/classes/Array.html)  
> array\*int “[R]eturns a new array built by concatenating the int  
> copies of self.”  
> Copies should be brand new independent copies, right?

No, copies are shallow copies. Consider, for example

irb(main):002:0\> class A; attr\_accessor :a; end  
=\> nil  
irb(main):003:0\> a = A.new  
=\> #\<A:0xb7c65b44\>  
irb(main):004:0\> a.a = 10  
=\> 10  
irb(main):005:0\> foo = [a]  
=\> [#\<A:0xb7c65b44 @a=10\>]  
irb(main):006:0\> foo \*= 3  
=\> [#\<A:0xb7c65b44 @a=10\>, #\<A:0xb7c65b44 @a=10\>, #\<A:0xb7c65b44 @a=10\>]  
irb(main):007:0\> a.a = 20  
=\> 20  
irb(main):008:0\> foo  
=\> [#\<A:0xb7c65b44 @a=20\>, #\<A:0xb7c65b44 @a=20\>, #\<A:0xb7c65b44 @a=20\>]

martin

---

<div class="post-metadata">

**Author:** ![kyle\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f6c823/32.png) [@kyle\_s](https://www.ruby-forum.com/u/kyle_s)\
**Post date:** [October 29, 2008, 5:29pm UTC](https://www.ruby-forum.com/t/bug-or-not-a-bug-array-int/152059/3 "2008-10-29T17:29:08Z")

</div>

Ahh.  
And upon not being lazy and looking at the C, I see this…  
ary2 = ary\_new(rb\_obj\_class(ary), len);

Which I’m guessing is equivalent to this in ruby (which I already knew  
would return the same array len times)  
ary2=Array.new(ary,len)

Any chance the document maintainer could slip the word “shallow” into  
the description of array\*?

🙂

---

<div class="post-metadata">

**Author:** ![kyle\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f6c823/32.png) [@kyle\_s](https://www.ruby-forum.com/u/kyle_s)\
**Post date:** [October 29, 2008, 6:38pm UTC](https://www.ruby-forum.com/t/bug-or-not-a-bug-array-int/152059/4 "2008-10-29T18:38:42Z")

</div>

Robert K. wrote:

> deep copy is more complex

… and in many cases impossible (e.g. open files/sockets; procs/blocks;  
any object with a singleton class)

---

<div class="post-metadata">

**Author:** ![kyle\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f6c823/32.png) [@kyle\_s](https://www.ruby-forum.com/u/kyle_s)\
**Post date:** [October 29, 2008, 5:55pm UTC](https://www.ruby-forum.com/t/bug-or-not-a-bug-array-int/152059/5 "2008-10-29T17:55:32Z")

</div>

On 29.10.2008 17:26, Kyle S. wrote:

> Ahh.  
> And upon not being lazy and looking at the C, I see this…  
> ary2 = ary\_new(rb\_obj\_class(ary), len);
> 
> Which I’m guessing is equivalent to this in ruby (which I already knew  
> would return the same array len times)  
> ary2=Array.new(ary,len)
> 
> Any chance the document maintainer could slip the word “shallow” into  
> the description of array\*?

Dunno. But all (or almost all) copies (e.g. dup, clone, Enumerable#map,  
Enumerable#select) do shallow copying only. So shallow is the rule and  
not particularly exceptional - as it is also more efficient and deep  
copy is more complex (i.e. deciding when to create a new object or just  
copy the reference). There are quite a few discussions of this topic in  
the archives…

For deep copies the idiom probably most often used is

copy = Marshal.load(Marshal.dump(obj))

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![kyle\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f6c823/32.png) [@kyle\_s](https://www.ruby-forum.com/u/kyle_s)\
**Post date:** [October 30, 2008, 7:56pm UTC](https://www.ruby-forum.com/t/bug-or-not-a-bug-array-int/152059/6 "2008-10-30T19:56:09Z")

</div>

On Thu, Oct 30, 2008 at 7:22 AM, Stefan R. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> As mentioned by others, shallow is the default (also to my knowledge in  
> most OO languages).  
> The moment you wish for deep copy is usually the moment you should  
> consider writing a proper class instead of deeply nesting  
> arrays/hashes/…
> 
> Regards  
> Stefan

Stefan, while I agree that in general you should write a proper class,  
the case I was talking about is a completely valid and normal use of  
multi-dimensional arrays in ruby. I’m guessing that duplicating a row  
in an array is not a rare occurrence either. I was just saying that  
maybe a mention of this should be added to the standard docs, as it’s  
a common pitfall. Bits are cheap 🙂 common pitfalls should be noted  
all over the place in the docs.

–Kyle

---

<div class="post-metadata">

**Author:** ![kyle\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f6c823/32.png) [@kyle\_s](https://www.ruby-forum.com/u/kyle_s)\
**Post date:** [October 30, 2008, 1:23pm UTC](https://www.ruby-forum.com/t/bug-or-not-a-bug-array-int/152059/7 "2008-10-30T13:23:50Z")

</div>

Kyle S. wrote:

> Ahh.  
> And upon not being lazy and looking at the C, I see this…  
> ary2 = ary\_new(rb\_obj\_class(ary), len);
> 
> Which I’m guessing is equivalent to this in ruby (which I already knew  
> would return the same array len times)  
> ary2=Array.new(ary,len)
> 
> Any chance the document maintainer could slip the word “shallow” into  
> the description of array\*?
> 
> 🙂

As mentioned by others, shallow is the default (also to my knowledge in  
most OO languages).  
The moment you wish for deep copy is usually the moment you should  
consider writing a proper class instead of deeply nesting  
arrays/hashes/…

Regards  
Stefan
