Как мне передать массив в аргументах командной строки ARGV?

#ruby

#ruby

Вопрос:

У меня есть следующее:

=== Моя программа test.rb

 def test (app, download, launch )
  for i in 0..(app.length - 1)do
    #DO SOMETHING HERE WITH THIS
    p  app[i].to_s   download[i].to_s   launch[i].to_s
  end
end
test (ARGV[0].split(//) , ARGV[2].split(//) ,ARGV[1].split(//))
  

=== другая программа «other.rb», которая анализирует и выполняет test.rb

 app = ["fda","asdf"]
down =  ["ok","nok"]
la = ["ok","ok"]
system("ruby test.rb #{app} #{down} #{la}")
  

Я хотел бы напечатать его примерно так:

 fda ok ok
asdf no nok
  

Однако он печатается следующим образом:

 foo 
dkk 
ano
aok
sk
d
f
  

Как я могу правильно передавать массивы в приложение?

Комментарии:

1. Это домашнее задание? Параметры и то, что вы пытаетесь сделать, кажутся скорее академическими, чем практичными.

Ответ №1:

Я скопировал ваш исходный код и вставил его в два файла:

test.rb:

 def test (app, download, launch )
  for i in 0..(app.length - 1)do
    #DO SOMETHING HERE WITH THIS
    p  app[i].to_s   download[i].to_s   launch[i].to_s
  end
end
test (ARGV[0].split(//) , ARGV[2].split(//) ,ARGV[1].split(//))
  

и test2.rb:

 app = ["fda","asdf"]
down =  ["ok","nok"]
la = ["ok","ok"]
system("ruby test.rb #{app} #{down} #{la}")
  

Используя Ruby 1.9.2p290, я получаю этот результат при запуске вашего кода:

 ruby test2.rb
test.rb:7: syntax error, unexpected ',', expecting ')'
test (ARGV[0].split(//) , ARGV[2].split(//) ,ARGV[1].split(//))
                        ^
test.rb:7: syntax error, unexpected ',', expecting $end
test (ARGV[0].split(//) , ARGV[2].split(//) ,ARGV[1].split(//))
  

Это говорит мне о том, что вы не точно сообщили о проблеме, которую вы видите.

Исправление синтаксической ошибки возвращает это:

 ruby test2.rb
"[[a"
"fos"
"dkd"
"a,f"
",]"
  

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

Просмотр данных, передаваемых вашим кодом, показывает, что аргументы:

 0 [fda,
1 asdf]
2 [ok,
3 nok]
4 [ok,
5 ok]
  

К вашему сведению, я получил те, которые используют этот фрагмент кода вместо test.rb :

 ARGV.each_with_index do |a, i|
  puts "#{i} #{a}"
end
  

Я бы ожидал этого, потому system("ruby test.rb #{app} #{down} #{la}") что не делает того, что вы думаете. Вот как выглядит фактическая команда, отправленная во вложенную оболочку при system ее обработке:

 test.rb [fda, asdf] [ok, nok] [ok, ok]
  

Опять же, это соответствует тому, как выглядят аргументы, когда приложение их видит.

Чтобы понять, что происходит, вам нужно прочитать документацию для system :

system([env,] command ... [,options]) -> true, false или nil

[...]

command ... - это одна из следующих форм.

[...]

 cmdname, arg1, ... : имя команды и один или несколько аргументов (без оболочки)

Итак, system позволяет нам отправлять все параметры отдельно, что действительно то, что вы хотите. Изменение test2.rb на:

 app  = %w[ fda asdf ]
down = %w[ ok  nok  ]
la   = %w[ ok  ok   ]

system(
  "echo",
  "test.rb",
  %Q["#{ app.join(',')  }"],
  %Q["#{ down.join(',') }"],
  %Q["#{ la.join(',')   }"]
)
  

дает мне это в командной строке:

 ruby test2.rb
test.rb "fda,asdf" "ok,nok" "ok,ok"
  

Что кажется немного более удобным. Из-за того, как system это работает, я могу очистить его и немного уменьшить до:

 app  = %w[ fda asdf ]
down = %w[ ok  nok  ]
la   = %w[ ok  ok   ]

system(
  "ruby",       # execute this
  "test.rb",    # with this script name
  app.join(','), down.join(','), la.join(',') # and these parameters
)
  

Просмотр того, что test.rb видит, показывает:

 ruby test2.rb
0 fda,asdf
1 ok,nok
2 ok,ok
  

Опять же, улучшение и ближе к тому, что ожидал ваш код.

Я не собираюсь заканчивать исправление вашего кода, потому что подозреваю, что это домашнее задание, а не практическое применение. Несколько советов, которые помогут вам:

  • Ваше использование split неверно, и я бы не туда его поместил.
  • Вы используете for не идиоматический Ruby. Посмотрите Array.each и узнайте, почему это предпочтительнее вместо for .
  • Ваше использование to_s не является необходимым, поскольку вы уже имеете дело со строками и символами.

Ответ №2:

вы могли бы использовать Thor, который является dsl для создания приложений командной строки