идиомы Ruby для использования параметров командной строки
Вопрос
Я пытаюсь освоить Ruby, портируя Perl-программу среднего размера (не объектно-ориентированную).Одна из моих личных идиом — устанавливать такие параметры:
use Getopt::Std;
our $opt_v; # be verbose
getopts('v');
# and later ...
$opt_v && print "something interesting\n";
В Perl я как бы стиснул зубы и позволил $opt_v быть (фактически) глобальным.
В Ruby более или менее точным эквивалентом будет
require 'optparse'
opts.on("-v", "--[no-]verbose", TrueClass, "Run verbosely") {
|$opt_verbose|
}
opts.parse!
end
где $opt_verbose — это глобальная переменная, к которой могут иметь доступ классы.Знание классов о таких глобальных флагах кажется...э...неправильный.Каков ОО-идиоматический способ сделать это?
- Пусть основная процедура позаботится обо всех вещах, связанных с опциями, а классы просто будут возвращать ей то, с чем она решит, как поступить?
- Должны ли классы реализовывать необязательное поведение (например, знать, как быть многословным) и устанавливать режим с помощью чего-то типа attr_writer?
обновлено: Спасибо за ответы, предлагающие optparse, но мне следовало прояснить, что это не так. как для обработки параметров командной строки, о которых я спрашиваю, но больше о взаимосвязи между параметрами командной строки, которые эффективно устанавливают глобальное состояние программы, и классами, которые в идеале должны быть независимыми от подобных вещей.
Решение
Некоторое время назад я наткнулся на этот пост в блоге (Тодд Верт), в котором представлен довольно длинный скелет сценариев командной строки в Ruby.Его скелет использует гибридный подход, при котором код приложения инкапсулируется в класс приложения, экземпляр которого создается, а затем выполняется путем вызова метода «запуска» объекта приложения.Это позволило сохранить параметры в переменной экземпляра всего класса, чтобы все методы объекта приложения могли получить к ним доступ, не раскрывая их другим объектам, которые могут использоваться в сценарии.
Я бы склонялся к использованию этого метода, при котором параметры содержатся в одном объекте и используют либо attr_writers, либо параметры параметров при вызовах методов для передачи соответствующих параметров любым дополнительным объектам.Таким образом, любой код, содержащийся во внешних классах, может быть изолирован от самих параметров — не нужно беспокоиться об именах переменных в основной процедуре изнутри thingy
класс, если ваши параметры установлены с помощью thingy.verbose=true
attr_writer или thingy.process(true)
вызов.
Другие советы
optparse библиотека является частью стандартного дистрибутива, поэтому вы сможете использовать ее, не требуя каких-либо сторонних компонентов.
Я не использовал его лично, но рельсы, кажется, широко используют его и как и Rspec, что, я думаю, является довольно солидным вотумом доверия
Этот пример из рельсов script/console
кажется, показывает, как использовать его довольно легко и красиво
первый удар в Google для "обработка параметров командной строки в Ruby" это статья о троллоп который кажется хорошим инструментом для этой работы.