Bạn có chắc chắn muốn xóa bài viết này không ?
Bạn có chắc chắn muốn xóa bình luận này không ?
Ruby Object Clone and Duplication
Ruby Object copy
Lately I've faced some Ruby Object Problems
Actually this is the OOP object copy problem.But I dont know much about OOP so...
Ok, enough trash talking. Let's do some code
I used rails c
for this mini testing
test = {:a => 1, :b => 2 }
a = test
b = test
a[:a] = 3
puts a
{:a => 3,:b => 2 }
puts b
{:a => 3,:b => 2 }
puts test
{:a => 3,:b => 2 }
Even I haven't touched b
and test
yet. Still these values are changed when I changed a
Solution :
Using dup
and clone
a = test.dup
a[:a] = 3
=> a = {:a => 3,:b => 2 }
b = test = {:a => 3,:b => 2 }
a = test.clone
a[:a] = 3
=> a = {:a => 3,:b => 2 }
b = test = {:a => 3,:b => 2 }
I couldnt find the different between these 2 methods
So I decided to go a little bit deeper
TEST1
dup
:
a = Object.new
def a.foo; :foo end
p a.foo
# => :foo
b = a.dup
p b.foo
# => undefined method `foo' for #<Object:0x007f8bc395ff00> (NoMethodError)
clone
:
a = Object.new
def a.foo; :foo end
p a.foo
# => :foo
b = a.clone
p b.foo
# => :foo
Frozen state :
a = Object.new
a.freeze
p a.frozen?
# => true
b = a.dup
p b.frozen?
# => false
c = a.clone
p c.frozen?
# => true
conclusion 1:
They both create a shallow copy of an object (meaning that they don't copy the objects that might be referenced within the copied object). However, #clone does two things that #dup doesn't:
copy the singleton class of the copied object
maintain the frozen status of the copied object
*https://coderwall.com/p/1zflyg/ruby-the-differences-between-dup-clone
Test 2:
class Klass
attr_accessor :str
end
module Foo
def foo; 'foo'; end
end
s1 = Klass.new #=> #<Klass:0x401b3a38>
s1.extend(Foo) #=> #<Klass:0x401b3a38>
s1.foo #=> "foo"
s2 = s1.clone #=> #<Klass:0x401b3a38>
s2.foo #=> "foo"
s3 = s1.dup #=> #<Klass:0x401b3a38>
s3.foo #=> NoMethodError: undefined method `foo' for #<Klass:0x401b3a38>
conclusion 2:
In general, clone and dup may have different semantics in descendant classes. While clone is used to duplicate an object, including its internal state, dup typically uses the class of the descendant object to create the new instance.
When using dup, any modules that the object has been extended with will not be copied.
*http://ruby-doc.org/core-2.2.3/Object.html#method-i-clone
Test 3:
Assume we had ActiveRecord working
camp = Campaign.find(1)
clone = camp.clone
dup = camp.dup
camp : {:id => 1, :name => "test campaign 1"}
clone : {:id => 1, :name => "test campaign 1"}
dup : {:id => nil, :name => "test campaign 1"}
conclusion 3:
clone
will have all of camp's attributes including id while dup
=> clone.save
will excute the update
method (update the camp
object)
and dup.save
will excute the new
method (create new object exactly the save attributes with camp
object)




