Ruby Object Clone and Duplication
Ruby
106
RubyOnRails
39
White

Duong Bach viết ngày 28/12/2015

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)

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Duong Bach

2 bài viết.
0 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
3 0
Rails scope and class method When I first read about scope: All scope methods will return an ActiveRecord::Relation object which will allow for ...
Duong Bach viết 2 năm trước
3 0
Bài viết liên quan
White
8 6
Chưa xem phần 2? Xem (Link) Trong bài viết này tôi giới thiệu cho các bạn về khái niệm function arity, một cách gọi mĩ miều của số lượng argument ...
Lơi Rệ viết hơn 2 năm trước
8 6
White
8 1
Tiếp theo (Link) Mình sẽ hướng dẫn cách test căn bản cho API mình tạo. Thật ra mà nói thì mình phải viết test trước khi làm nhưng mà để tránh việc...
My Mai viết hơn 2 năm trước
8 1
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
2 bài viết.
0 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!