diff --git a/lib/getoptlong.rb b/lib/getoptlong.rb index c825962..575da51 100644 --- a/lib/getoptlong.rb +++ b/lib/getoptlong.rb @@ -537,55 +537,42 @@ def set_options(*arguments) @argument_flags.clear arguments.each do |arg| - if !arg.is_a?(Array) - raise ArgumentError, "the option list contains non-Array argument" + unless defined?(arg.each) + raise ArgumentError, "option list must be iterable `#{arg.inspect}'" end # - # Find an argument flag and it set to `argument_flag'. + # Partition the arguments into argument flags and option names. # - argument_flag = nil - arg.each do |i| - if ARGUMENT_FLAGS.include?(i) - if argument_flag != nil - raise ArgumentError, "too many argument-flags" - end - argument_flag = i - end - end + flags, opts = arg.each.partition { |flag| ARGUMENT_FLAGS.include?(flag) } - raise ArgumentError, "no argument-flag" if argument_flag == nil + # + # Handle obvious errors before iterating. + # + raise ArgumentError, "no argument-flag" if flags.empty? + raise ArgumentError, "too many argument-flags" if flags.size > 1 + raise ArgumentError, "no option name" if opts.empty? - canonical_name = nil - arg.each do |i| - # - # Check an option name. - # - next if i == argument_flag - begin - if !i.is_a?(String) || i !~ /\A-([^-]|-.+)\z/ - raise ArgumentError, "an invalid option `#{i}'" - end - if (@canonical_names.include?(i)) - raise ArgumentError, "option redefined `#{i}'" - end - rescue - @canonical_names.clear - @argument_flags.clear - raise + # + # Validate options. + # + opts.each do |i| + unless /\A-([^-]|-.+)\z/.match?(i) + raise ArgumentError, "an invalid option `#{i}'" end - - # - # Register the option (`i') to the `@canonical_names' and - # `@canonical_names' Hashes. - # - if canonical_name == nil - canonical_name = i + if @canonical_names.include?(i) + raise ArgumentError, "option redefined `#{i}'" end - @canonical_names[i] = canonical_name - @argument_flags[i] = argument_flag end - raise ArgumentError, "no option name" if canonical_name == nil + + # + # Register the option aliases to the `@canonical_names' and + # `@argument_flags' Hashes. + # + opts.each do |name| + @canonical_names[name] = opts.first + @argument_flags[name] = flags.first + end end return self end diff --git a/test/test_getoptlong.rb b/test/test_getoptlong.rb index 0cd370b..94be5e2 100644 --- a/test/test_getoptlong.rb +++ b/test/test_getoptlong.rb @@ -104,7 +104,7 @@ def test_new_with_bad_array e = assert_raise(ArgumentError) do GetoptLong.new('foo') end - assert_match(/option list contains non-Array argument/, e.message) + assert_match(/option list must be iterable/, e.message) end def test_new_with_empty_subarray