Thành thật mà nói, tôi đã sử dụng biểu mẫu thứ nhất (mở lại lớp), vì nó cảm thấy tự nhiên hơn, nhưng câu hỏi của bạn buộc tôi phải nghiên cứu về chủ đề và đây là kết quả.
Vấn đề với việc mở lại lớp là nó sẽ âm thầm xác định một lớp mới nếu lớp gốc mà bạn dự định mở lại, vì một lý do nào đó không được xác định tại thời điểm này. Kết quả có thể khác nhau:
Nếu bạn không ghi đè lên bất kỳ phương pháp nhưng chỉ làm tăng thêm những cái mới và việc thực hiện ban đầu được xác định (ví dụ, tập tin, nơi mà các lớp được định nghĩa ban đầu được tải) sau đó tất cả mọi thứ sẽ được rồi.
Nếu bạn xác định lại một số phương pháp và bản gốc được tải sau, các phương pháp của bạn sẽ bị ghi đè trở lại với phiên bản gốc.
Trường hợp thú vị nhất là khi bạn sử dụng tiêu chuẩn autoloading hoặc một số cơ chế tải lại ưa thích (như được sử dụng trong Rails) để tải/tải lại lớp học. Một số giải pháp dựa trên số const_missing được gọi khi bạn tham chiếu hằng số không xác định. Trong trường hợp đó, cơ chế tự động tải sẽ cố gắng tìm định nghĩa của lớp chưa xác định và tải nó. Nhưng nếu bạn đang xác định lớp học của riêng bạn (trong khi bạn dự định mở lại đã được xác định) nó sẽ không bị 'mất tích' nữa và bản gốc có thể không bao giờ được tải vì cơ chế tự động tải sẽ không được kích hoạt.
Mặt khác, nếu bạn sử dụng class_eval
bạn sẽ được thông báo ngay lập tức nếu lớp không được định nghĩa vào lúc này. Ngoài ra, khi bạn tham chiếu lớp khi bạn gọi phương thức class_eval
của mình, mọi cơ chế tự động tải sẽ có cơ hội xác định định nghĩa của lớp và tải nó.
Có ý nghĩ đó class_eval
có vẻ là một cách tiếp cận tốt hơn. Mặc dù, tôi rất sẵn lòng nghe một số ý kiến khác.
Nguồn
2012-04-26 18:33:46
có thể trùng lặp của [khỉ vá vs lớp \ _eval?] (Http://stackoverflow.com/questions/9399358/monkey-patching-vs-class-eval) – akostadinov