2012-08-01 40 views
12

What's the difference between Ruby's dup and clone methods? mô tả sự khác biệt về hành vi của dupclone. Nhưng khi nào tôi nên sử dụng dup và khi nào tôi nên sử dụng clone thay thế?Khi nào thì dùng dup và khi nào thì dùng clone trong Ruby?

Ví dụ từ các dự án thực tế thảo luận về lý do tại sao chúng sử dụng lệnh dup thay vì sao chép, hoặc ngược lại, sẽ là lý tưởng cho câu hỏi này.

Ngoài ra, giải thích lý do tại sao hai phương pháp khác nhau tồn tại sẽ hữu ích. Điều này có thể ám chỉ đến các phát biểu từ những người sáng tạo của Ruby, hoặc kiểm tra các phương thức như dupclone bằng các ngôn ngữ ảnh hưởng đến Ruby.

+0

Bản sao có thể có của [Sự khác nhau giữa phương pháp sao chép và sao chép của Ruby là gì?] (Http://stackoverflow.com/questions/10183370/whats-the-difference-between-rubys-dup-and-clone-methods) – OlehZiniak

Trả lời

7

Đúng là clone sao chép frozen trạng thái của một đối tượng, trong khi dup không:

o = Object.new 
o.freeze 

o.clone.frozen? 
#=> true 

o.dup.frozen? 
#=> false 

clone cũng sẽ sao chép các phương thức singleton của đối tượng trong khi dup không:

o = Object.new 
def o.foo 
    42 
end 

o.clone.respond_to?(:foo) 
#=> true 

o.dup.respond_to?(:foo) 
#=> false 

Điều này dẫn tôi đến giả định rằng clone đôi khi được hiểu là cung cấp bản sao "sâu hơn" hơn dup. Dưới đây là một số trích dẫn về chủ đề:

Comment on ActiveRecord::Base#initialize_dup from Rails 3:

đối tượng lừa đã không có id được giao và được coi là kỷ lục mới. Lưu ý rằng đây là bản sao "nông" vì bản sao chỉ sao chép thuộc tính của đối tượng , chứ không phải các liên kết của đối tượng. Mức độ của một bản sao "sâu" là ứng dụng cụ thể và do đó là trái với các ứng dụng để thực hiện theo nhu cầu của nó.

An article about deep copies in Ruby:

Có một phương pháp đáng nói, clone. Phương pháp clone thực hiện tương tự như dup với một sự phân biệt quan trọng: nó được mong đợi rằng các đối tượng sẽ ghi đè phương thức này với một đối tượng có thể làm các bản sao sâu.

But then again, theres deep_dup in Rails 4:

Trả về một bản sao sâu sắc về đối tượng nếu nó duplicable. Nếu không trùng lặp, trả về self.

and also ActiveRecord::Core#dup and #clone in Rails 4:

clone - giống hệt với phương pháp nhân bản của Ruby. Đây là bản sao "nông". Được cảnh báo rằng các thuộc tính của bạn không được sao chép. [...] Nếu bạn cần một bản sao băm thuộc tính của mình, vui lòng sử dụng phương thức #dup.

Điều đó có nghĩa là ở đây, từ dup được sử dụng để chỉ lại bản sao sâu. Theo như tôi thấy, có vẻ như không có sự đồng thuận trong cộng đồng, ngoại trừ việc bạn nên sử dụng clonedup trong trường hợp khi bạn cần một tác dụng phụ cụ thể của một trong hai.

Cuối cùng, tôi thấy dup thường xuyên hơn trong mã Ruby so với clone. Tôi chưa bao giờ sử dụng clone cho đến nay, và tôi sẽ không cho đến khi tôi rõ ràng cần phải.

+0

Bây giờ có vẻ như tôi đã sử dụng 'dup', trừ khi bạn có lý do để sử dụng' clone' ('dup' có vẻ đơn giản hơn). Nhưng có lẽ đó là bởi vì tôi hiện đang quan tâm đến việc nhân bản một băm. Vì vậy, tôi không quan tâm đến trạng thái đông lạnh và một lớp singleton. –

4

Cả DUP & Có thể sử dụng CLONE để tạo bản sao nông của đối tượng. Cả hai bản sao các biến cá thể của obj. Nhưng chúng ta cần phải chọn lọc trong cách sử dụng của họ.

ít sự khác biệt giữa đây là những

1) CLONE bản cả FROZEN và trạng thái nhiễm độc của một đối tượng, nơi như DUP chỉ bản sao nhiễm trạng thái của một đối tượng.

2) Với CLONE, bạn có thể sao chép bất kỳ phương thức đơn lẻ nào của đối tượng nhưng DUP không hỗ trợ điều này.

CLONE được sử dụng để nhân bản một đối tượng, bao gồm trạng thái nội bộ của nó, DUP thường sử dụng lớp của đối tượng con cháu để tạo cá thể mới.

Tôi đã có một số kinh nghiệm cay đắng trong khi sử dụng DUP để nhân bản hàng ActiveRecord, điều này đã kết thúc bằng việc mất bản gốc cùng làm việc tốt với CLONE.

Như tôi đã quấn mình trong sự nhầm lẫn, tôi thấy nó rõ ràng trong một Article of Open Source is Wide Open

+0

"Có ba cách để sao chép trong Ruby: #dup, #clone và '='." - Làm thế nào để '=' sao chép? –

+0

Tôi không hiểu sâu hơn về cách '=' sao chép, nhưng nó cũng tạo ra một bản sao nông. Dưới đây là một [ví dụ tốt] (http://thingsaaronmade.com/blog/ruby-shallow-copy-surprise.html) để bắt đầu, nhưng tóm lại, toán tử gán không tạo bản sao của giá trị, nó chỉ đơn giản là các bản sao tham chiếu đến đối tượng –

+0

Chỉ cần lưu ý: 'Marshal :: load (Marshal.dump (foo))' hoạt động, nhưng có thể gây rắc rối với mô hình cơ sở dữ liệu. – sandstrom

Các vấn đề liên quan