4

Using OptionParser for string argument input and hash assignment. What is the best way to read-in multiple variables for a single argument? How do I then assign those to a hash to reference? Here is what I have so far:

large_skus = Hash.new
small_skus = Hash.new

OptionParser.new do |opts|

opts.on("-b", "--brands bName1,bName2,bNameN", String, "Check specific brands by name") do |b|
 options[:brands] = b.split(",")
end

opts.on("-l", "--large lSku1,lSku2,lSkuN", String, "Large SKUs - List CSVs") do |l|
 options[:large_skus] = l.split(",")
 ##For each sku given
 brandName = options[:brands]
 large_skus[brandName] = l[$sku].to_i
 ##
end

opts.on("-s", "--small sSku1,sSku2,sSkuN", String, "Small SKUs - List CSVs") do |s|
 options[:small_skus] = s.split(",")
 ##For each sku given
 brandName = options[:brands]
 small_skus[brandName] = s[$sku].to_i
 ##
end

end.parse!(ARGV)
user453366
  • 75
  • 1
  • 5

2 Answers2

7

Given an input of:

 ruby test.rb --brands bName1,bName2,bNameN --large lSku1,lSku2,lSkuN --small wQueue1,wQueue2,wQueueN

This code

#!/usr/bin/env ruby

require 'ap'
require 'optparse'

options = {}
OptionParser.new do |opts|

  opts.on("-b", "--brands bName1,bName2,bNameN", Array, "Check specific brands by name") do |b|
    options[:brands] = b
  end

  opts.on("-l", "--large lSku1,lSku2,lSkuN", Array, "Large SKUs - List CSVs") do |l|
    options[:large_skus] = l
  end

  opts.on("-s", "--small wQueue1,wQueue2,wQueueN", Array, "Small SKUs - List CSVs") do |s|
    options[:small_skus] = s
  end

end.parse!(ARGV)

ap options

Produces this output:

{
        :brands => [
        [0] "bName1",
        [1] "bName2",
        [2] "bNameN"
    ],
    :large_skus => [
        [0] "lSku1",
        [1] "lSku2",
        [2] "lSkuN"
    ],
    :small_skus => [
        [0] "wQueue1",
        [1] "wQueue2",
        [2] "wQueueN"
    ]
}

Notice that instead of using types of String for each option, I'm using Array. That lets OptionParser do the heavy lifting of parsing the elements into an array. From that point it's up to you what you do with the array elements.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
  • Understood, arrays are a good option. What about the hash assignment? I updated my original post, I noticed some typos (queue vs. sku). The idea being that I wouldn't have to iterate the small or large sku arrays by index number to find their matching/associated brand. – user453366 Oct 03 '10 at 22:59
  • It's not real obvious what you are trying to do based on your example code. Your code has variables that are missing ($sku) and you don't explain what your intention is with the large_skus and small_skus hashes. – the Tin Man Oct 04 '10 at 03:05
5

I think you are approaching this the wrong way. You want your users to have to keep track of the order of the parameters they input but you don't want to do it yourself in the code!

How about you don't ask anybody to keep track of what goes with what and make it explicit:

ruby test.rb --input bName1,lSku1,wQueue1 --input bName2,lSku2,wQueue2 --input bNameN,lSkuN,wQueueN

Code:

opts.on("--input <brand,Large_Skus,Small_Skus>", "input description",
        "NOTE: Can be used more than once.") do |opt|
  list = opt.split(',')
  unless list.lenght == 3
    raise "some error because you didn't place all arguments"
  end
  options[:input].push list
end 

result:

[ [ 'bName1', 'lSku1', 'wQueue1' ],
  [ 'bName2', 'lSku2', 'wQueue2' ],
  [ 'bNameN', 'lSkuN', 'wQueueN' ] ]
DavidGamba
  • 3,503
  • 2
  • 30
  • 46