[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Bug or not a bug? array*=int

Kyle Schmitt

10/29/2008 3:30:00 PM

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

According to http://www.ruby-doc.org/core/classes/...
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]]

6 Answers

Martin DeMello

10/29/2008 4:13:00 PM

0

On Wed, Oct 29, 2008 at 8:30 AM, Kyle Schmitt <kyleaschmitt@gmail.com> wrote:
> So I'm wondering, is this a bug, or not a bug, or a type-o in the docs?
>
> According to http://www.ruby-doc.org/core/classes/...
> 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

Kyle Schmitt

10/29/2008 4:26:00 PM

0

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*?

:)

Robert Klemme

10/29/2008 4:53:00 PM

0

On 29.10.2008 17:26, Kyle Schmitt 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

Brian Candler

10/29/2008 5:38:00 PM

0

Robert Klemme wrote:
> deep copy is more complex

... and in many cases impossible (e.g. open files/sockets; procs/blocks;
any object with a singleton class)
--
Posted via http://www.ruby-....

Stefan Rusterholz

10/30/2008 12:23:00 PM

0

Kyle Schmitt 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
--
Posted via http://www.ruby-....

Kyle Schmitt

10/30/2008 6:55:00 PM

0

On Thu, Oct 30, 2008 at 7:22 AM, Stefan Rusterholz <apeiros@gmx.net> 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