Skip to content

Instantly share code, notes, and snippets.

@trans
Created August 10, 2015 03:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save trans/63e3515c38649d1c5faa to your computer and use it in GitHub Desktop.
Save trans/63e3515c38649d1c5faa to your computer and use it in GitHub Desktop.
Crystal port of Clik
def cli(opts : Hash(String,Proc))
cli(ARGV.dup, opts)
end
def cli(argv : Array(String), opts : Hash(String,Proc))
args = [] of String
# Split option aliases.
h = {} of String => ->
opts.each do |k,v|
k.to_s.split(/\s+/).each { |o| h[o] = v }
end
opts = h
# Convert single dash flags into multiple flags.
a = [] of String
argv.each do |v|
if v[0,1] == "-" && v[1,1] != "-"
a.concat(v[1..-1].chars.map{|c| "-#{c}"})
else
a << v
end
end
argv = a
while argv.any?
item = argv.shift
flag = opts[item]
if flag
# Work around lambda semantics in 1.8.7.
arity = [flag.arity, 0].max
# Raise if there are not enough parameters
# available for the flag.
if argv.size < arity
raise ArgumentError.new
end
# Call the lambda with N items from argv,
# where N is the lambda's arity.
#flag.call(*argv.shift(arity).values)
if arity == 0
flag.call()
elsif arity == 1
flag.call(*argv.values_at(0))
end
else
# Collect the items that don't correspond to
# flags.
args << item
end
end
# TODO: should we replace the argv given with args?
args
end
require "../src/clik"
# Simple example
opts = {} of Symbol => (String | Bool)
argv = ["-x"]
cli argv, {
"-x" => ->{ opts[:x] = true }
}
opts[:x].assert === true
# Another example
opts = {} of Symbol => (String | Bool)
argv = ["-w", "-f", "hello"]
cli argv, {
"-w --whatever" => ->{ opts[:w] = true },
"-f --file" => ->(f){ opts[:f] = f },
"-h --help" => ->{ puts "help" }
}
opts[:w].assert == true
opts[:f].assert == "hello"
@trans
Copy link
Author

trans commented Aug 10, 2015

Error in ./test_click.cr:8: instantiating 'cli(Array(String), Hash(String, ( -> Bool)))'

cli argv, {
^~~

in /home/trans/Workspace/clik/src/clik.cr:52: wrong number of arguments for '( -> Void)#call' (1 for 0)

      flag.call(*argv.values_at(0))
           ^~~~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment