2012-03-08 3 views
3

Я пытаюсь передать массив в ruby-скрипт из командной строки и столкнуться с некоторой проблемой.Передача массива в качестве аргумента команды

Вот проблема:

require 'pp' 

def foo(arr1, var, arr2, var2) 
    puts arr1.class 
    pp arr1 
    pp arr1[0] 
    puts arr2.class 
    pp arr2 
    pp arr2[0] 
end 

foo [1, 2], 3, [5, 6], 8 

Вот результат:

Array 
[1, 2] 
1 
Array 
[5, 6] 
5 

Все это хорошо до сих пор. Теперь я могу изменить мой сценарий, чтобы принять аргумент из командной строки:

require 'pp' 

def foo(arr1,var) 
    puts arr1.class 
    pp arr1 
    pp arr1[0] 
end 
foo ARGV[0],3 

Вот результат:

jruby test.rb [1, 2], 3, [5, 6], 8 
String 
"[1," 
91 
String 
"2]," 
50 

Как вы можете видеть, массив передается в виде строки и обр [0] в основном печатает значение ascii.

Итак, вопрос в том, как передать массив из командной строки, надеюсь, в одной строке. Также я считаю, что этот вопрос связан со всеми вызовами оболочки, чем просто рубином?

Я использую оболочку bash.

Update: Просто обновил вопрос, чтобы указать, что может быть несколько массивов в различных позициях

ответ

0

Вы можете использовать Eval хотя вы можете открыть дыру в безопасности:

require 'pp' 

def foo(arr1, var, arr2, var2) 
    puts arr1.class 
    pp arr1 
    pp arr1[0] 
    puts arr2.class 
    pp arr2 
    pp arr2[0] 
end 

eval("foo " + ARGV.join(" ")) 

Результат

Array 
[1, 2] 
1 
Array 
[5, 6] 
5 

Надеется, что это помогает

+0

Thanx Edu. Массив, который я передаю, представляет собой массив строк, путь к файлу должен быть конкретным. Было бы очень полезно, если бы вы могли дать правильный синтаксис для передачи массива строки, например: jruby test.rb ["path1", "path2"], 3, ["name1", "name2"], 8 – codeObserver

+0

Добавление " и побег их сделал трюк. jruby test.rb [\ "path1 \", \ "path2 \"], 3, [\ "name1 \", \ "name2 \"], 8 .. Thnx, это сработало для меня ! – codeObserver

+0

Привет, CodeObserver, вы можете изменить eval на это: eval ("foo" + ARGV.join ("") .gsub (/ (\ w +) /, '"\ 1"')), так что вы не необходимо избегать передачи аргументов. – Edu

2

Вот list способов сделать это. Держитесь подальше от решений, основанных на eval. Мой любимый (хотя я не знаю, рубин, но это моя любимая:

irb(main):001:0> s = "[5,3,46,6,5]" 
=> "[5,3,46,6,5]" 
irb(main):002:0> a = s.scan(/\d+/) 
=> ["5", "3", "46", "6", "5"] 
irb(main):003:0> a.map!{ |s| s.to_i } 
=> [5, 3, 46, 6, 5] 
+0

Thnx. Христианин. Я пытаюсь назвать это оболочкой, а не irb. Похоже, что eval - единственный вариант. – codeObserver

+0

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

2

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

require 'trollop' 

opts = Trollop.options do 
    opt :array, 'an array', type: :ints 
    opt :val, 'a value', type: :int 
end 

puts "array: #{opts[:array].inspect}" 
puts "val: #{opts[:val].inspect}" 

Тогда вы можете do:

$ ruby test.rb -a 1 2 -v 3 
array: [1, 2] 
val: 3 

И дополнительные приятно:

$ ruby test.rb --help 
Options: 
--array, -a <i+>: an array 
--val, -v <i>: a value 
--help, -h: Show this message 
+0

Thnx Jon. Это выглядит как интересный вариант. Однако я получаю некоторую синтаксическую ошибку, и doc явно не объясняет мой вариант. ========== синтаксическая ошибка, неожиданно ':' opt: array, 'array', type:: ints =========. Также я обновил свой вопрос, чтобы сделать его более понятным. – codeObserver

+0

@codeObserver: вы используете старую версию Ruby. Новый синтаксис хэша был введен в Ruby 1.9.0. –