2010-11-17 28 views
5

Tôi có một struct trong mã Ruby của tôi trông hơi như thế nàyTại sao String :: sub!() Thay đổi bản gốc của một đối tượng nhân bản trong Ruby?

Parameter = Struct.new(:name, :id, :default_value, :minimum, :maximum) 

sau, tôi tạo ra một thể hiện của struct này sử dụng

freq = Parameter.new('frequency', 15, 1000.0, 20.0, 20000.0) 

Tại một số điểm, tôi cần một bản sao chính xác của việc này struct, vì vậy tôi gọi

newFreq = freq.clone 

Sau đó, tôi thay đổi newFreq 's tên

newFreq.name.sub!('f', 'newF') 

Điều gì, kỳ diệu, thay đổi freq.name, quá!

Bài tập đơn giản như newFreq.name = 'newFrequency' không thay đổi freq.

Đây có phải là cách này được cho là hoạt động không?

Chỉnh sửa: Bạn nên sử dụng lớp học thay vì cấu trúc và quá tải clone để tạo bản sao sâu?

Trả lời

10

newFreq là bản sao nông của freq. Điều đó có nghĩa là mỗi tài liệu tham khảo được lưu trữ bên trong của newFreq điểm đến đối tượng như là những cái được lưu trữ trong freq. Bạn có thể thay đổi nơi tham chiếu điểm độc lập (newFreq.name = newFreq.name.sub 'f','newF'), nhưng nếu bạn gọi một phương thức làm biến đổi đối tượng, cả hai newFreqfreq sẽ bị ảnh hưởng.

Xem thêm http://en.wikipedia.org/wiki/Object_copy

8

Phương pháp Object#clone thực hiện bản sao cạn. Bạn cần bản sao sâu để hoàn thành công việc.

Làm theo this link để tìm hiểu về bản sao sâu trong Ruby.

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