Class Clip::Parser
In: lib/clip.rb
Parent: Object

Methods

errors   flag   help   help_with   opt   optional   parse   req   required   to_s   valid?  

Attributes

banner  [RW]  Set the usage ‘banner’ displayed when calling to_s to display the usage message. If not set, the default will be used. If the value is set this completely replaces the default
remainder  [R]  Returns any remaining command line arguments that were not parsed because they were neither flags or option/value pairs

Public Instance methods

Returns a Hash of errors (by the long name) of any errors encountered during parsing. If you simply want to display error messages to the user, you can just print out a call to the to_s method.

[Source]

# File lib/clip.rb, line 226
    def errors
      @errors
    end

Declare a parameter as a simple boolean flag. This declaration will create a "question" method matching the given long. For example, declaring with the name of ‘verbose’ will create a method on your parser called verbose?.

options

Valid options are:

  • desc: Descriptive text for the flag

[Source]

# File lib/clip.rb, line 126
    def flag(short, long, options={})
      check_args(short, long)

      short = short.to_sym
      long = long.gsub('-', '_').to_sym
      self.class.class_eval do
        define_method("flag_#{long}") do
          instance_variable_set("@#{long}", true)
        end

        define_method("#{long}?") do
          instance_variable_get("@#{long}")
        end
      end

      self.options[long] = Flag.new(short, long, options)
      self.options[short] = self.options[long]
      self.order << self.options[long]
      check_longest(long)
    end

Returns a formatted String indicating the usage of the parser, formatted to fit within 80 display columns.

[Source]

# File lib/clip.rb, line 233
    def help
      out = ""
      if banner
        out << "#{banner}\n"
      else
        out << "Usage:\n"
      end

      order.each do |option|
        line = sprintf("-%-2s --%-#{@longest}s  ",
                       option.short,
                       option.long.to_s.gsub('_', '-'))

        out << line
        if line.length + option.description.length <= 80
          out << option.description
        else
          rem = 80 - line.length
          desc = option.description
          i = 0
          while i < desc.length
            out << "\n" if i > 0
            j = [i + rem, desc.length].min
            while desc[j..j] =~ /[\w\d]/
              j -= 1
            end
            chunk = desc[i..j].strip
            out << " " * line.length if i > 0
            out << chunk
            i = j + 1
          end
        end

        if option.has_default?
          out << " (default: #{option.default})"
        end

        if option.required?
          out << " REQUIRED"
        end
        out << "\n"
      end
      out
    end

Override the flag to trigger help usage. By default the short flag ’-h’ and long flag ’—help’ will trigger displaying usage. If you need to override this, particularly in the case of ’-h’, call this method

[Source]

# File lib/clip.rb, line 43
    def help_with(short, long="--help")
      @help_short = short
      @help_long = long
    end
opt(short, long, options={}, &block)

Alias for optional

Declare an optional parameter for your parser. This creates an accessor method matching the long parameter and a present method long?. The short parameter indicates the single-letter equivalent. Options that use the ’-’ character as a word separator are converted to method names using ‘_’. For example the name ‘exclude-files’ would create two methods named exclude_files and exclude_files?.

When the :multi option is enabled, the associated accessor method will return an Array instead of a single scalar value.

options

Valid options include:

  • desc: a helpful description (used for printing usage)
  • default: a default value to provide if one is not given
  • multi: indicates that mulitple values are okay for this param.
  • block: an optional block to process the parsed value

Note that specifying the :multi option means that the parameter can be specified several times with different values, or that a single comma-separated value can be specified which will then be broken up into separate tokens.

[Source]

# File lib/clip.rb, line 70
    def optional(short, long, options={}, &block)
      check_args(short, long)

      short = short.to_sym
      long = long.gsub('-', '_').to_sym

      var_name = "@#{long}".to_sym
      self.class.class_eval do
        define_method("#{long}=".to_sym) do |v|
          begin
            v = yield(v) if block_given?
            instance_variable_set(var_name, v)
          rescue StandardError => e
            @valid = false
            @errors[long] = e.message
          end
        end

        define_method(long.to_sym) do
          instance_variable_get(var_name)
        end

        define_method("#{long}?") do
          !instance_variable_get(var_name).nil?
        end
      end

      self.options[short] = self.options[long] =
        Option.new(short, long, options)

      self.order << self.options[long]
      check_longest(long)
    end

Parse the given args and set the corresponding instance fields to the given values. If any errors occurred during parsing you can get them from the Hash returned by the errors method.

[Source]

# File lib/clip.rb, line 159
    def parse(args)
      @valid = true
      args = Shellwords::shellwords(args) unless args.kind_of?(Array)
      consumed = []
      option = nil

      args.each do |token|
        case token
        when @help_long, @help_short
          puts help
          exit 0

        when /\A--\z/
          consumed << token
          break

        when /^-(-)?\w/
          consumed << token
          param = token.sub(/^-(-)?/, '').gsub('-', '_').to_sym
          option = options[param]
          if option.nil?
            @errors[param] = "Unrecognized parameter"
            @valid = false
            next
          end

          if option.kind_of?(Flag)
            option.process(self, nil)
            option = nil
          end
        else
          if option
            consumed << token
            option.process(self, token)
            option = nil
          end
        end
      end

      @remainder = args - consumed

      # Find required options that are missing arguments
      options.each do |param, opt|
        if opt.kind_of?(Option) and self.send(opt.long).nil?
          if opt.required?
            @valid = false
            @errors[opt.long.to_sym] = "Missing required parameter: #{opt.long}"
          elsif opt.has_default?
            opt.process(self, opt.default)
          end
        end
      end
    end
req(short, long, options={}, &block)

Alias for required

Declare a required parameter for your parser. If this parameter is not provided in the parsed content, the parser instance will be invalid (i.e. where valid? returns false).

This method takes the same options as the optional method.

[Source]

# File lib/clip.rb, line 112
    def required(short, long, options={}, &block)
      optional(short, long, options.merge({ :required => true }), &block)
    end

Returns a formatted String of the help method prefixed by any parsing errors. Either way you have one method to call to let your users know what to do.

[Source]

# File lib/clip.rb, line 282
    def to_s
      out = ""
      unless valid?
        out << "Errors:\n"
        errors.each do |field, msg|
          out << "#{field}: #{msg}\n"
        end
      end
      out << help
    end

Indicates whether or not the parsing process succeeded. If this returns false you probably just want to print out a call to the to_s method.

[Source]

# File lib/clip.rb, line 217
    def valid?
      @valid
    end

[Validate]