
Currently we handle options in several ways, and it is hard to remember what code needs an option string ("--foo"), what needs only the name ("foo") and what needs an Option object. Now that Option objects can act as strings and be converted to JSON, we can start using them instead of passing around strings between Formula objects, Tab objects, and ARGV-style arrays. The Options class is a special collection that can be queried for the inclusion of options in any form: '--foo', 'foo', or Option.new("foo").
79 lines
1.0 KiB
Ruby
79 lines
1.0 KiB
Ruby
class Option
|
|
include Comparable
|
|
|
|
attr_reader :name, :description, :flag
|
|
|
|
def initialize(name, description=nil)
|
|
@name = name.to_s[/^(?:--)?(.+)$/, 1]
|
|
@description = description.to_s
|
|
@flag = "--#{@name}"
|
|
end
|
|
|
|
def to_s
|
|
flag
|
|
end
|
|
alias_method :to_str, :to_s
|
|
|
|
def to_json
|
|
flag.inspect
|
|
end
|
|
|
|
def <=>(other)
|
|
name <=> other.name
|
|
end
|
|
|
|
def eql?(other)
|
|
other.is_a?(self.class) && hash == other.hash
|
|
end
|
|
|
|
def hash
|
|
name.hash
|
|
end
|
|
end
|
|
|
|
class Options
|
|
include Enumerable
|
|
|
|
def initialize(*args)
|
|
@options = Set.new(*args)
|
|
end
|
|
|
|
def each(*args, &block)
|
|
@options.each(*args, &block)
|
|
end
|
|
|
|
def <<(o)
|
|
@options << o
|
|
self
|
|
end
|
|
|
|
def +(o)
|
|
Options.new(@options + o)
|
|
end
|
|
|
|
def -(o)
|
|
Options.new(@options - o)
|
|
end
|
|
|
|
def *(arg)
|
|
@options.to_a * arg
|
|
end
|
|
|
|
def empty?
|
|
@options.empty?
|
|
end
|
|
|
|
def as_flags
|
|
map(&:flag)
|
|
end
|
|
|
|
def include?(o)
|
|
any? { |opt| opt == o || opt.name == o || opt.flag == o }
|
|
end
|
|
|
|
def to_a
|
|
@options.to_a
|
|
end
|
|
alias_method :to_ary, :to_a
|
|
end
|