Clive

Types

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.)

Object

The Object type will accept any value and return it, without modification. It is the basic type.

String

The String type will accept anything except nil and returns it as a String. This is the default value set for arguments.

Symbol

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

Integer

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

StrictInteger

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: ...

Binary

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

Octal

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

Hexadecimal

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}

Float

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

Boolean

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

Pathname

The Pathname type accepts any non nil value, and returns it cast to a Pathname object.

Range

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"

Array

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']

Time

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

Regexp

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/

Creating Your Own Type

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