Clive allows you to use a variety of types (and create your own) which are passed to options and commands to alter arguments passed in.
class CLI < Clive
opt :num, as: Integer
# or use one of these
# opt :num, type: Integer
# opt :num, kind: Integer
# opt :num, types: Integer
end
Here we use the Integer
type to turn the value passed to --num
into an Integer, but also importantly to check that what is passed looks like an Integer. (It actually takes anything that looks like a number, StrictInteger will only allow values which look like Integers; more below.)
The Object type will accept any value and return it, without modification. It is the basic type.
The String type will accept anything except nil
and returns it as a String. This is the default value set for arguments.
The Symbol type will accept any value except nil
and returns it as a
Symbol (by calling #to_sym
on it).
class CLI < Clive
opt :type, as: Symbol
end
r = CLI.run
p r.type
# ./cli --type debug
#=> :debug
The Integer type will accept any value which looks like a number and returns it as an Integer.
class CLI < Clive
opt :size, as: Integer
end
r = CLI.run
p r.size
# ./cli --size 500
#=> 500
# ./cli --size 5.679
#=> 5
The StrictInteger type only accepts values that look like integers. It then returns the number as an Integer.
class CLI < Clive
opt :size, as: StrictInteger
end
r = CLI.run
p r.size
# ./cli --size 500
#=> 500
# ./cli --size 5.679
#=> Clive::Parser::MissingArgumentError: ...
The Binary type takes a binary number, which may optionally begin with "0b", and returns the value as an Integer.
class CLI < Clive
opt :byte, as: Binary
end
r = CLI.run
p r.byte
# ./cli --byte 0b1001001
#=> 73
The Octal type takes an octal number which may optionally be prefixed with "0" or "0o". It returns the number as an Integer.
class CLI < Clive
opt :oct, as: Octal
end
r = CLI.run
p r.oct
# ./cli --oct 0o25
#=> 21
The Hexadecimal type matches any hexadecimal number which can optionally have the "0x" prefix. It returns an Integer.
class CLI < Clive
opt :r, as: Hexadecimal
opt :g, as: Hexadecimal
opt :b, as: Hexadecimal
end
r = CLI.run
p r.to_h
# ./cli -r ff -g 00 -b 00
#=> {:r => 255, :g => 0, :b => 0}
The Float type matches any floating point number and returns a Float.
class CLI < Clive
opt :ratio, as: Float
end
r = CLI.run
p r.ratio
# ./cli --ratio 0.34
#=> 0.34
The Boolean type accepts "true", "t", "yes", "y" and "on", returning true
; or, "false", "f", "no", "n" and "off", returning false
.
class CLI < Clive
opt :auto_merge, as: Boolean
end
r = CLI.run
p r.auto_merge
# ./cli --auto-merge off
#=> false
The Pathname type accepts any non nil
value, and returns it cast to a Pathname object.
The Range type accepts any value accepted as a range in ruby, eg. 1..5
, "a"..."z"
, etc. and also 1-5
which is equivalent to 1..5
. Note that it will always return a Range of String objects!
class CLI < Clive
opt :range, as: Range
end
r = CLI.run
p r.range
# ./cli --range 200-500
#=> "200".."500"
The Array type accepts a comma delimited list of values. It returns an Array of String values.
class CLI < Clive
opt :names, as: Array
end
r = CLI.run
p r.names
# ./cli --names John,Ringo,Paul,George
#=> ['John', 'Ringo', 'Paul', 'George']
The Time type accepts any value which can be parsed by Time.parse
.
class CLI < Clive
opt :start_at, as: Time
end
r = CLI.run
p r.start_at
# ./cli --start-at 11:56
#=> 2012-06-11 11:56:00 0100
The Regexp type accepts any value which looks like a ruby regular expression.
class CLI < Clive
opt :filter, as: Regexp
end
r = CLI.run
p r.filter
# ./cli --filter /test|spec/
#=> /test|spec/
Lets go through creating a new type. Say, for instance, we want to be able to create a Range of Integers, we'll call it IntegerRange.
class IntegerRange < Clive::Type::Range
def typecast(arg)
(super.min.to_i)..(super.max.to_i)
end
end
We're using the normal Range type as the base. Each type needs to define two methods, #valid?(arg)
and #typecast(arg)
, which respectively check the argument is valid for the type, and then covert to the correct type. We're going to use the Range's #valid?
method and can use most of the #typecast
method. We just need to map the result to integers. It can now be used like this;
class CLI < Clive
opt :numbers, as: IntegerRange
end
r = CLI.run
p r.numbers
# ./cli --numbers 1..5
#=> 1..5