Как передать пустую строку в командную строку, используя OptionParser - PullRequest
1 голос
/ 05 января 2020

Я пытаюсь написать сценарий, который получает некоторые аргументы, некоторые из которых могут быть пустыми.

Кажется, что OptionParser Ruby не разрешает это и выдает (OptionParser::InvalidArgument).

Код:

require 'optparse'

options = {}
OptionParser.new do |opt|

  opt.on('--might_be_empty might_be_empty', String) { |o| options[:might_be_empty] = o }

end.parse!

puts "might_be_empty: #{options[:might_be_empty]}"

Счастливый поток:

ruby ./for_stack.rb --might_be_empty "some_real_data"
might_be_empty: some_real_data

Когда значение пусто:

ruby ./for_stack.rb --might_be_empty ""
./for_stack.rb:10:in `<main>': invalid argument: --might_be_empty  (OptionParser::InvalidArgument)

Как я могу сказать OptionParser разрешить пустое строки?

Ответы [ 3 ]

3 голосов
/ 05 января 2020

Не указывайте тип приведения или используйте Object вместо String. Оба ведут себя одинаково.

opt.on('--might_be_empty might_be_empty') { ... }
# ..or
opt.on('--might_be_empty might_be_empty', Object) { ... }

Тест:

ruby ./for_stack.rb --might_be_empty "some_real_data"
might_be_empty: some_real_data

ruby ./for_stack.rb --might_be_empty ""
might_be_empty: 
1 голос
/ 05 января 2020

В соответствии с документацией для OptionParser Type Coercion , передача String - это не просто "ничего не делать":

String - Любая непустая строка

Однако, если вы просто оставите для параметра Аргумент значение on (которое указывает на документы для make_switch):

Приемлемо Формат аргумента опции должен быть предопределен с помощью #accept или #accept или Regexp. Это может появиться один раз или быть назначено как String, если не присутствует, в противном случае возникает ArgumentError.

Несмотря на небольшую путаницу, что он «назначен как String, если не присутствует», он не «назначен как непустая строка если не присутствует ", и он по умолчанию будет передавать вам любую строку и работать так, как вы хотите:

opt.on('--might_be_empty might_be_empty') { |o| options[:might_be_empty] = o }

# is optional
% ruby example.rb       
might_be_empty:
# if passed, must have a value
% ruby example.rb --might_be_empty 
Traceback (most recent call last):
example.rb:8:in '<main>': missing argument: --might_be_empty (OptionParser::MissingArgument)
# can pass an empty string
% ruby example.rb --might_be_empty ""
might_be_empty:
# can pass any string
% ruby example.rb --might_be_empty "not empty"
might_be_empty: not empty

Если вы не хотите просто оставлять шаблон аргумента выключенным, вы можете создавать пользовательские конверсии , хотя мне это кажется излишним.

0 голосов
/ 05 января 2020

Option Parser допускает необязательные значения:

Запуск этого несколько раз:

require 'optparse'

options = {}
OptionParser.new do |opt|

  opt.on('--might_be_empty [arg]') { |o| options[:might_be_empty] = o }

end.parse!

puts 'options[:might_be_empty].has_key? is %s' % options.has_key?(:might_be_empty)
puts 'options[:might_be_empty] is "%s"' % options[:might_be_empty]
puts 'options[:might_be_empty] is a %s' % options[:might_be_empty].class
pp ARGV

Показывает мне:

$ ruby test.rb -m
options[:might_be_empty].has_key? is true
options[:might_be_empty] is ""
options[:might_be_empty] is a NilClass
[]

$ ruby test.rb -m foo
options[:might_be_empty].has_key? is true
options[:might_be_empty] is "foo"
options[:might_be_empty] is a String
[]

$ ruby test.rb -m 1
options[:might_be_empty].has_key? is true
options[:might_be_empty] is "1"
options[:might_be_empty] is a String
[]

Это задокументировано пару раз в пример кода , но явно не указано в тексте:

def perform_inplace_option(parser)
  # Specifies an optional option argument
  parser.on("-i", "--inplace [EXTENSION]",
            "Edit ARGV files in place",
            "(make backup if EXTENSION supplied)") do |ext|
    self.inplace = true
    self.extension = ext || ''
    self.extension.sub!(/\A\.?(?=.)/, ".")  # Ensure extension begins with dot.
  end
end

Также обратите внимание, что вам не нужно приводить возвращаемое значение, поскольку оно уже является String. Любые значения, передаваемые из командной строки, являются строками, так как они вырваны из ARGV.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...