Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > PLEASE HELP...dup is not working correctly in the following code

Reply
Thread Tools

PLEASE HELP...dup is not working correctly in the following code

 
 
timr
Guest
Posts: n/a
 
      12-29-2009
#dup creates a copy of an object with a different object_id. As
follows:
>> a = [1,2,3]

=> [1, 2, 3]
>> b = a.dup

=> [1, 2, 3]
>> b << 1000

=> [1, 2, 3, 1000]
>> a

=> [1, 2, 3]
>> b

=> [1, 2, 3, 1000]

Changing b does't change a because b is a copy of a with a different
object_id.

However, unlike the irb session, the following code shows that
modification of the dupped object is somehow changing the original.
WTF? (you may want to change the font to courier to get the maze to
line up correctly). This behavior is so strange. I can see no
significant differences between the usage in the irb session and in
this code, yet the behavior is very different. Please explain if you
have any insights.
Thanks,
Tim

@maze1 = %{#####################################
# # # #A # # #
# # # # # # ####### # ### # ####### #
# # # # # # # # #
# ##### # ################# # #######
# # # # # # # # #
##### ##### ### ### # ### # # # # # #
# # # # # # B# # # # # #
# # ##### ##### # # ### # # ####### #
# # # # # # # # # # # #
# ### ### # # # # ##### # # # ##### #
# # # # # # #
#####################################}
class Maze
attr_accessor :maze

#initialize creates a @maze array with each row a sub array
def initialize(maze_name)
@maze = maze_name.split(/\n/).collect{|row| row.split(//)}
@maze_dup = @maze.dup
end
def write_(r, c)
@maze_dup[r][c] = "a"
end
def report
puts "@maze:"
@maze.each{|r| p r.join}
puts "@maze_dup:"
@maze_dup.each{|r| p r.join}
end
end

maze1 = Maze.new(@maze1)
maze1.report
maze1.write_(0,0)
maze1.report
maze1.write_(1,1)
maze1.report


# >> @maze:
# >> "#####################################"
# >> "# # # #A # # #"
# >> "# # # # # # ####### # ### # ####### #"
# >> "# # # # # # # # #"
# >> "# ##### # ################# # #######"
# >> "# # # # # # # # #"
# >> "##### ##### ### ### # ### # # # # # #"
# >> "# # # # # # B# # # # # #"
# >> "# # ##### ##### # # ### # # ####### #"
# >> "# # # # # # # # # # # #"
# >> "# ### ### # # # # ##### # # # ##### #"
# >> "# # # # # # #"
# >> "#####################################"
# >> @maze_dup:
# >> "#####################################"
# >> "# # # #A # # #"
# >> "# # # # # # ####### # ### # ####### #"
# >> "# # # # # # # # #"
# >> "# ##### # ################# # #######"
# >> "# # # # # # # # #"
# >> "##### ##### ### ### # ### # # # # # #"
# >> "# # # # # # B# # # # # #"
# >> "# # ##### ##### # # ### # # ####### #"
# >> "# # # # # # # # # # # #"
# >> "# ### ### # # # # ##### # # # ##### #"
# >> "# # # # # # #"
# >> "#####################################"
# >> @maze:
# >> "a####################################"
# >> "# # # #A # # #"
# >> "# # # # # # ####### # ### # ####### #"
# >> "# # # # # # # # #"
# >> "# ##### # ################# # #######"
# >> "# # # # # # # # #"
# >> "##### ##### ### ### # ### # # # # # #"
# >> "# # # # # # B# # # # # #"
# >> "# # ##### ##### # # ### # # ####### #"
# >> "# # # # # # # # # # # #"
# >> "# ### ### # # # # ##### # # # ##### #"
# >> "# # # # # # #"
# >> "#####################################"
# >> @maze_dup:
# >> "a####################################"
# >> "# # # #A # # #"
# >> "# # # # # # ####### # ### # ####### #"
# >> "# # # # # # # # #"
# >> "# ##### # ################# # #######"
# >> "# # # # # # # # #"
# >> "##### ##### ### ### # ### # # # # # #"
# >> "# # # # # # B# # # # # #"
# >> "# # ##### ##### # # ### # # ####### #"
# >> "# # # # # # # # # # # #"
# >> "# ### ### # # # # ##### # # # ##### #"
# >> "# # # # # # #"
# >> "#####################################"
# >> @maze:
# >> "a####################################"
# >> "#a# # #A # # #"
# >> "# # # # # # ####### # ### # ####### #"
# >> "# # # # # # # # #"
# >> "# ##### # ################# # #######"
# >> "# # # # # # # # #"
# >> "##### ##### ### ### # ### # # # # # #"
# >> "# # # # # # B# # # # # #"
# >> "# # ##### ##### # # ### # # ####### #"
# >> "# # # # # # # # # # # #"
# >> "# ### ### # # # # ##### # # # ##### #"
# >> "# # # # # # #"
# >> "#####################################"
# >> @maze_dup:
# >> "a####################################"
# >> "#a# # #A # # #"
# >> "# # # # # # ####### # ### # ####### #"
# >> "# # # # # # # # #"
# >> "# ##### # ################# # #######"
# >> "# # # # # # # # #"
# >> "##### ##### ### ### # ### # # # # # #"
# >> "# # # # # # B# # # # # #"
# >> "# # ##### ##### # # ### # # ####### #"
# >> "# # # # # # # # # # # #"
# >> "# ### ### # # # # ##### # # # ##### #"
# >> "# # # # # # #"
# >> "#####################################"


 
Reply With Quote
 
 
 
 
Seebs
Guest
Posts: n/a
 
      12-29-2009
On 2009-12-29, timr <(E-Mail Removed)> wrote:
> However, unlike the irb session, the following code shows that
> modification of the dupped object is somehow changing the original.


No, it isn't.

You have two separate arrays.

However, each of those arrays contains the same strings -- the first string
of each array is the same object.

You want a deep copy (where you duplicate all the objects in the array,
not just the arrays). Something like:

@maze_dup = @maze.map { |x| x.dup }

.... I think.

-s
--
Copyright 2009, all wrongs reversed. Peter Seebach / http://www.velocityreviews.com/forums/(E-Mail Removed)
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
 
Reply With Quote
 
 
 
 
timr
Guest
Posts: n/a
 
      12-29-2009
On Dec 28, 9:41*pm, Seebs <(E-Mail Removed)> wrote:
> On 2009-12-29, timr <(E-Mail Removed)> wrote:
>
> > However, unlike the irb session, the following code shows that
> > modification of the dupped object is somehow changing the original.

>
> No, it isn't.
>
> You have two separate arrays.
>
> However, each of those arrays contains the same strings -- the first string
> of each array is the same object.
>
> You want a deep copy (where you duplicate all the objects in the array,
> not just the arrays). *Something like:
>
> @maze_dup = @maze.map { |x| x.dup }
>
> ... I think.


You are right about the strings having the same object_ids in each
object, which explains why the modification on the dupped object
affects the original strings. That helps. But the suggested strategy
doesn't solve the problem:

>> a = [['a', 'b'], ['c','d']]

=> [["a", "b"], ["c", "d"]]
>> a.each{|r| r.each{|letter| p letter.object_id}}

4442750
4442740
4442710
4442700
=> [["a", "b"], ["c", "d"]]
>> b = a.map{|r| r.each{|letter| letter.dup}}

=> [["a", "b"], ["c", "d"]]
>> b.each{|r| r.each{|letter| p letter.object_id}}

4442750
4442740
4442710
4442700

Still the same object_ids for all of the contents.
Tim


>
> -s
> --
> Copyright 2009, all wrongs reversed. *Peter Seebach / (E-Mail Removed)://www.seebs.net/log/<-- lawsuits, religion, and funny pictureshttp://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!


 
Reply With Quote
 
Seebs
Guest
Posts: n/a
 
      12-29-2009
On 2009-12-29, timr <(E-Mail Removed)> wrote:
> You are right about the strings having the same object_ids in each
> object, which explains why the modification on the dupped object
> affects the original strings. That helps. But the suggested strategy
> doesn't solve the problem:


Hmm.

>>> a = [['a', 'b'], ['c','d']]

>=> [["a", "b"], ["c", "d"]]
>>> a.each{|r| r.each{|letter| p letter.object_id}}

> 4442750
> 4442740
> 4442710
> 4442700
>=> [["a", "b"], ["c", "d"]]
>>> b = a.map{|r| r.each{|letter| letter.dup}}


This doesn't seem right. The inner loop (which is the one I think
we care about) is using each, not map. So we never actually return
the array consisting of all the duplicated letters.

If you have an array of arrays, I think you need to use map at both
levels.

irb(main):001:0> a = [['a', 'b'], ['c','d']]
=> [["a", "b"], ["c", "d"]]
irb(main):002:0> b = a.map {|r| r.map{|l| l.dup}}
=> [["a", "b"], ["c", "d"]]
irb(main):003:0> a.each{|r| r.each{|letter| p letter.object_id}}
2152912244
2152912216
2152912132
2152912104
=> [["a", "b"], ["c", "d"]]
irb(main):004:0> b.each{|r| r.each{|letter| p letter.object_id}}
2152886456
2152886316
2152886232
2152886176
=> [["a", "b"], ["c", "d"]]

What's throwing you off here is that .each returns the array object
it started with.

So "r.each {...}" always returns r, unmodified.

-s
--
Copyright 2009, all wrongs reversed. Peter Seebach / (E-Mail Removed)
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
 
Reply With Quote
 
Josh Cheek
Guest
Posts: n/a
 
      12-29-2009
[Note: parts of this message were removed to make it a legal post.]

On Mon, Dec 28, 2009 at 11:40 PM, timr <(E-Mail Removed)> wrote:

> #dup creates a copy of an object with a different object_id. As
> follows:
> >> a = [1,2,3]

> => [1, 2, 3]
> >> b = a.dup

> => [1, 2, 3]
> >> b << 1000

> => [1, 2, 3, 1000]
> >> a

> => [1, 2, 3]
> >> b

> => [1, 2, 3, 1000]
>
>


This is the difference

$ irb
>> a = [ 'w' , 'x' , 'y' ]

=> ["w", "x", "y"]

>> b = a.dup

=> ["w", "x", "y"]

>> a << 'z'

=> ["w", "x", "y", "z"]

>> b

=> ["w", "x", "y"]

>> a[0] << 'x'

=> "wx"

>> a

=> ["wx", "x", "y", "z"]

>> b

=> ["wx", "x", "y"]


a and b are different arrays, but they each contain the same objects.

I think the only way to make a deep copy is to explicitly dup everything in
the array also, or to use marshall. I'm not sure why there isn't a deep copy
method.

 
Reply With Quote
 
Phillip Gawlowski
Guest
Posts: n/a
 
      12-29-2009
On 29.12.2009 07:15, timr wrote:

> You are right about the strings having the same object_ids in each
> object, which explains why the modification on the dupped object
> affects the original strings. That helps. But the suggested strategy
> doesn't solve the problem:


irb(main):001:0> array = ["string"]
=> ["string"]
irb(main):002:0> array_dup = []
=> []
irb(main):003:0> array_dup[0] = array[0].clone
=> "string"
irb(main):004:0> array_dup[0].object_id
=> 30816948
irb(main):005:0> array[0].object_id
=> 30838824

--
Phillip Gawlowski

 
Reply With Quote
 
timr
Guest
Posts: n/a
 
      12-29-2009
On Dec 28, 10:20*pm, Seebs <(E-Mail Removed)> wrote:
> On 2009-12-29, timr <(E-Mail Removed)> wrote:
>
> > You are right about the strings having the same object_ids in each
> > object, which explains why the modification on the dupped object
> > affects the original strings. That helps. But the suggested strategy
> > doesn't solve the problem:

>
> Hmm.
>
> >>> a = [['a', 'b'], ['c','d']]

> >=> [["a", "b"], ["c", "d"]]
> >>> a.each{|r| r.each{|letter| p letter.object_id}}

> > 4442750
> > 4442740
> > 4442710
> > 4442700
> >=> [["a", "b"], ["c", "d"]]
> >>> b = a.map{|r| r.each{|letter| letter.dup}}

>
> This doesn't seem right. *The inner loop (which is the one I think
> we care about) is using each, not map. *So we never actually return
> the array consisting of all the duplicated letters.
>
> If you have an array of arrays, I think you need to use map at both
> levels.
>
> irb(main):001:0> a = [['a', 'b'], ['c','d']]
> => [["a", "b"], ["c", "d"]]
> irb(main):002:0> b = a.map {|r| r.map{|l| l.dup}}
> => [["a", "b"], ["c", "d"]]
> irb(main):003:0> a.each{|r| r.each{|letter| p letter.object_id}}
> 2152912244
> 2152912216
> 2152912132
> 2152912104
> => [["a", "b"], ["c", "d"]]
> irb(main):004:0> b.each{|r| r.each{|letter| p letter.object_id}}
> 2152886456
> 2152886316
> 2152886232
> 2152886176
> => [["a", "b"], ["c", "d"]]
>
> What's throwing you off here is that .each returns the array object
> it started with.
>
> So "r.each {...}" always returns r, unmodified.
>
> -s
> --
> Copyright 2009, all wrongs reversed. *Peter Seebach / (E-Mail Removed)://www.seebs.net/log/<-- lawsuits, religion, and funny pictureshttp://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!


I was just going to post that correction after I realized that
mistake. Thanks for the help.
 
Reply With Quote
 
Rimantas Liubertas
Guest
Posts: n/a
 
      12-29-2009
> #dup creates a copy of an object with a different object_id. As
> follows:

<=E2=80=A6>

>> a =3D ["bar", "baz"]

=3D> ["bar", "baz"]
>> b =3D a.dup

=3D> ["bar", "baz"]
>> c =3D Marshal.load(Marshal.dump(a))

=3D> ["bar", "baz"]
>> b[0] << "s"

=3D> "bars"
>> b

=3D> ["bars", "baz"]
>> a

=3D> ["bars", "baz"]
>> c

=3D> ["bar", "baz"]
>> a.object_id

=3D> 2157344160
>> b.object_id

=3D> 2157338800
>> c.object_id

=3D> 2157328340
>> a[0].object_id

=3D> 2157344140
>> b[0].object_id

=3D> 2157344140
>> c[0].object_id

=3D> 2157328320

Regards,
Rimantas
--
http://rimantas.com

 
Reply With Quote
 
Seebs
Guest
Posts: n/a
 
      12-29-2009
On 2009-12-29, timr <(E-Mail Removed)> wrote:
> I was just going to post that correction after I realized that
> mistake. Thanks for the help.


Thanks for asking the question with enough detail, and illustrations,
that it was *possible* to help.

-s
--
Copyright 2009, all wrongs reversed. Peter Seebach / (E-Mail Removed)
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
 
Reply With Quote
 
timr
Guest
Posts: n/a
 
      12-29-2009
On Dec 28, 10:49*pm, Rimantas Liubertas <(E-Mail Removed)> wrote:
> > #dup creates a copy of an object with a different object_id. As
> > follows:

>
> <>
>
>
>
>
>
> >> a = ["bar", "baz"]

> => ["bar", "baz"]
> >> b = a.dup

> => ["bar", "baz"]
> >> c = Marshal.load(Marshal.dump(a))

> => ["bar", "baz"]
> >> b[0] << "s"

> => "bars"
> >> b

> => ["bars", "baz"]
> >> a

> => ["bars", "baz"]
> >> c

> => ["bar", "baz"]
> >> a.object_id

> => 2157344160
> >> b.object_id

> => 2157338800
> >> c.object_id

> => 2157328340
> >> a[0].object_id

> => 2157344140
> >> b[0].object_id

> => 2157344140
> >> c[0].object_id

>
> => 2157328320
>
> Regards,
> Rimantas
> --http://rimantas.com


This is in effect the deep copy of a complex array containing strings
that we were pining for. I think it is easier to do it this ways than
to map through all of the nested arrays. Thanks for the irb demo of
its use.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
The Web server reported the following error when attempting to create or open the Web project located at the following URL: 'http://localhost/822319ev1'. 'HTTP/1.1 500 Internal Server Error'. chanmm ASP .Net 2 09-07-2010 07:37 AM
PLease help me.Wots the problem with following code....? alankrit@gmail.com C++ 5 05-30-2006 12:02 AM
PLease help me.Wots the problem with following code....? alankrit@gmail.com C Programming 7 05-29-2006 05:42 PM
RE: The Web server reported the following error when attempting to create or open the Web project located at the following URL: <URL> =?Utf-8?B?VHJldm9yIEJlbmVkaWN0IFI=?= ASP .Net 0 06-07-2004 07:36 AM
Re: please can someone explain the following code. suzy ASP .Net 3 07-31-2003 02:07 PM



Advertisments