コマンドを作成するためのDSLを提供するgemを解析するオプションがあります。実際には、次のように表示されることがよくあります。
option :ints, Integer, arity: [1, -1], on_multiple: :append
option :floats, Float, arity: [1, -1], on_multiple: :append
option :complex, Complex, arity: [1, -1], on_multiple: :append
これらはクラスメソッドです。ご覧のとおり、あまり乾燥していません。このようなものを書く方が良いでしょう:
scope arity: [1, -1], on_multiple: :append do
option :ints, Integer
option :floats, Float
option :complex, Complex
end
に与えられたオプションハッシュをに与えられたものとscope
透過的にマージさせるためoption
。それは私が立ち往生しているところです。後でマージできるように、共通オプションをどこに保存するかわかりません。
何か案は?
option
すべてをに転送しますOption#new
:
def option(*args, &block)
# self is a class that represents a command
self.options << Option.new(*args, &block)
end
要求に応じて、サポートgemの使用を削除したコードを次に示します。
def initialize(key, *args, &block)
# Retrieve the options hash from the argument array.
options = args.last.is_a?(Hash) ? args.pop : {}
# The rest of the implementation...
type = args.find { |arg| arg.is_a? Module }
strings = args.flatten.select do |arg|
arg.is_a? String
end.group_by do |arg|
arg =~ Parser::Regexp::SWITCH ? :switches : :description
end
self.key = key
self.names = strings.fetch(:switches) { [ Option.name_from(key) ] }
self.description = options.fetch :description, strings.fetch(:description, []).first
self.on_multiple = options.fetch :on_multiple, :replace
self.arity = options.fetch :arity, nil
self.default = options.fetch :default, nil
self.required = options.fetch :required, false
self.type = type || String
self.handler = block
end