Я пишу маленькое приложение командной строки Ruby, которое использует fileutils
из стандартной библиотеки для операций файла. В зависимости от того, как пользователь вызывает приложение, я захочу включать также FileUtils
, FileUtils::DryRun
или FileUtils::Verbose
.
С тех пор include
является частным, тем не менее, я не могу поместить логику для выбора в объект initialize
метод. (Который был моей первой мыслью, с тех пор я мог просто передать информацию о выборе пользователя в качестве параметра к new
.) я придумал две опции, которые, кажется, работают, но я не доволен также:
Установите глобальную переменную в пространстве имен приложения на основе выбора пользователя и затем сделайте условное выражение включает в класс:
class Worker
case App::OPTION
when "dry-run"
include FileUtils::DryRun
etc.
Создайте подклассы, где единственная разница который версия FileUtils
они включают. Выберите соответствующий, в зависимости от выбора пользователя.
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
Первый метод кажется СУШИЛКОЙ, но я надеюсь, что существует что-то более простое, о котором я не думал.
Так что, если он частный?
class Worker
def initialize(verbose=false)
if verbose
(class <<self; include FileUtils::Verbose; end)
else
(class <<self; include FileUtils; end)
end
touch "test"
end
end
Сюда входит FileUtils :: something
, в частности метакласс Worker
, а не в основном классе Worker
. Таким образом, разные рабочие процессы могут использовать разные FileUtils
.