#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
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”]]
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”]]
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.
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.
=> [[“a”, “b”], [“c”, “d”]]
the array consisting of all the duplicated letters.
2152912216
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 S. / [email protected]://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.
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.
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: