Ok, vì vậy tôi đã tái cấu trúc mã của mình trong ứng dụng Rails nhỏ trong một nỗ lực để loại bỏ trùng lặp, và nói chung làm cho cuộc sống của tôi dễ dàng hơn (như tôi thích một cuộc sống dễ dàng). Một phần của việc tái cấu trúc này, đã di chuyển mã phổ biến cho hai mô hình của tôi thành một mô-đun mà tôi có thể bao gồm nơi tôi cần nó.Ruby mixins và gọi siêu phương pháp
Cho đến nay, rất tốt. Có vẻ như nó sẽ thành công, nhưng tôi vừa mới gặp một vấn đề mà tôi không chắc chắn làm thế nào để có được xung quanh. Mô-đun (mà tôi đã gọi là có thể gửi), sẽ chỉ là mã xử lý fax, gửi thư điện tử hoặc in một tệp PDF của tài liệu. Vì vậy, ví dụ, tôi có một đơn đặt hàng, và tôi có Đơn đặt hàng nội bộ (được viết tắt là tưởng tượng theo ISO).
Vấn đề tôi đã xảy ra, là tôi muốn một số biến được khởi tạo (được khởi tạo cho những người không đánh vần đúng: P) sau khi đối tượng được tải, vì vậy tôi đã sử dụng móc after_initialize. Không vấn đề gì ... cho đến khi tôi bắt đầu thêm một số mixin khác.
Vấn đề tôi có, là tôi có thể có một after_initialize
trong bất kỳ một trong mixins của tôi, vì vậy tôi cần phải bao gồm một siêu cuộc gọi vào lúc bắt đầu để đảm bảo mixin khác after_initialize
cuộc gọi được gọi . Đó là tuyệt vời, cho đến khi tôi kết thúc gọi điện thoại siêu và tôi nhận được một lỗi vì không có siêu để gọi.
Dưới đây là một ví dụ nhỏ, trong trường hợp tôi đã không được lộn xộn đủ:
class Iso < ActiveRecord::Base
include Shared::TracksSerialNumberExtension
include Shared::OrderLines
extend Shared::Filtered
include Sendable::Model
validates_presence_of :customer
validates_associated :lines
owned_by :customer
order_lines :despatched # Mixin
tracks_serial_numbers :items # Mixin
sendable :customer # Mixin
attr_accessor :address
def initialize(params = nil)
super
self.created_at ||= Time.now.to_date
end
end
Vì vậy, nếu mỗi một trong những mixins có một cuộc gọi after_initialize, với một siêu cuộc gọi, làm thế nào tôi có thể ngăn chặn rằng cuộc gọi siêu mới nhất từ việc tăng lỗi? Làm thế nào tôi có thể kiểm tra rằng phương pháp siêu tồn tại trước khi tôi gọi nó?
downvoted bởi vì nó không phải là một giải pháp chung. Vấn đề là bạn không biết liệu super có tồn tại hay không, do đó, hãy bắt cóc ActiveRecord :: Base # after_initialize vào sự tồn tại, bạn tạo một điểm mà mã của bạn sẽ bị ngắt nếu/khi ActiveRecord thêm Base # after_initialize, hoặc arity của nó bị thay đổi ; nó là beter xa để có điều kiện gọi nó nếu nó được xác định. – yaauie
@yaauie - chắc chắn, tôi có thể đặt một 'nâng cao 'oh không' nếu phương pháp.bao gồm? (: After_initialize)' trước khỉ con, nhưng điều đó sẽ làm cho ví dụ khó hiểu hơn ... Thật dễ dàng để bắt kịp trong chi tiết tất cả các trường hợp cạnh mà bài học thực tế ở đây (chỉ cần vá một phương pháp cơ bản trong) sẽ bị lạc trong tiếng ồn. –
monkeypatching không phải là một giải pháp chung và không nên - nói chung - được khuyến khích. Một câu trả lời liên quan đến một monekypatch một lần mà * có thể * xảy ra để làm việc dẫn đến mã phức tạp và không cần thiết, đặc biệt là nếu bạn không có quyền kiểm soát tất cả các cách lên chuỗi thừa kế. – yaauie