Tôi đang viết một ứng dụng dòng lệnh Ruby nhỏ sử dụng fileutils
từ thư viện chuẩn cho các thao tác tệp. Tùy thuộc vào cách người dùng gọi ứng dụng, tôi sẽ muốn bao gồm FileUtils
, FileUtils::DryRun
hoặc FileUtils::Verbose
.Làm thế nào tôi có thể chọn phiên bản của một mô-đun để bao gồm động trong Ruby?
Vì include
là riêng tư, tuy nhiên, tôi không thể đặt logic để chọn phương thức initialize
của đối tượng. (Đó là suy nghĩ đầu tiên của tôi, kể từ đó tôi có thể chuyển thông tin về lựa chọn của người dùng như một tham số cho new
.) Tôi đã đưa ra hai tùy chọn có vẻ hiệu quả, nhưng tôi không hài lòng với một trong hai:
Đặt một biến toàn cầu trong không gian tên của ứng dụng dựa trên sự lựa chọn của người dùng, và sau đó làm một điều kiện bao gồm trong lớp:
class Worker case App::OPTION when "dry-run" include FileUtils::DryRun etc.
Tạo sub-lớp học, nơi sự khác biệt duy nhất là phiên bản
FileUtils
chúng bao gồm. Chọn tùy chọn phù hợp, tùy thuộc vào lựa chọn của người dùng.class Worker include FileUtils # shared Worker methods go here end class Worker::DryRun < Worker include FileUtils::DryRun end class Worker::Verbose < Worker include FileUtils::Verbose end
Phương pháp đầu tiên dường như DRY-er, nhưng tôi hy vọng rằng có một cái gì đó đơn giản hơn mà tôi chưa nghĩ đến.
"Vậy điều gì" nghe có vẻ đúng với tôi. (Đây là * chính xác * điều đơn giản hơn tôi không thấy.) Cảm ơn. – Telemachus
Rất tiếc, lỗi của tôi. Mã mà tôi đã đưa ra trước đây sẽ sửa đổi lớp 'Worker' để tất cả' Worker 'sẽ sử dụng cùng một thiết lập. Bây giờ nó thực sự sử dụng metaclass và cho phép cài đặt trước khi làm việc. – taw
thay vì '(lớp << tự; bao gồm FileUtils; kết thúc)' bạn cũng có thể sử dụng 'extend FileUtils'. –