3

コマンドを作成するための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

GitHubのオリジナル

4

1 に答える 1

2

RailsのObject#with_optionsを見て、それをスワイプして自分で使用します。

于 2012-05-18T02:01:44.623 に答える