SETTING PARAMETERS OF A RUBY CLASS THROUGH COMMAND LINE

In this post, I want to address two things:

  1. How to run a ruby class through command line? This is rather simple and just need few lines (see if __FILE__ = $0 in the code below)
  2. How to set configuration parameters of a class either through command line or through another class ? This was much more challenging to figure out then the first problem. I found the solution in OptionParser class.

Assumption: I assume that you are familiar with the OptionParser ruby library. If not, I recommend looking at some of these articles

Solution

Code:

require 'rubygems'
require 'optparse'

class SayHello

       # Define some class variables to
       # store configuration parameters
       attr_reader :optparse, :options, :mandatory, :arguments

      def initialize(arguments)
          @options = {}
          @optparse = OptionParser.new()
          set_mandatory
          set_arguments(arguments)
          set_options
          validate
      end

      #Set mandatory configuration parameters
      def set_mandatory
          @mandatory = [:name]
      end

      #Handle arguments
      def set_arguments(arguments)
         return if arguments.nil?
         if(arguments.kind_of?(String))
            @arguments = arguments.split(/s{1,}/)
         elsif (arguments.kind_of?(Array))
            @arguments = arguments
         else
            raise Exception, "Expecting either String or an Array"
         end
      end

     #Use OptionParser library and
     # define some parameters
     def set_options
         @optparse.banner = "Usage: ruby #{File.basename(__FILE__)} --[no]-debug"

         #First parameter definition
         @options[:debug] = false
         @optparse.on('--[no-]debug','Print debug statements'){|opt| @options[:debug] = opt }

         #Second Parameter definition
         @options[:name] = nil
         @optparse.on('-n','--name LIST',Array,'Say hello to'){|opt|
            @options[:name] = opt
         }
     end

     #Validate that mandatory parameters are specified
     def validate
         begin
            @optparse.parse!(@arguments)
            missing = @mandatory.select{|p| @options[p].nil? }
            if not missing.empty?
                puts "Missing options: #{missing.join(', ')}"
                puts @optparse
            end
         rescue OptionParser::ParseError,
                OptionParser::InvalidArgument,
                OptionParser::InvalidOption,
                OptionParser::MissingArgument
                puts $!.to_s
                puts @optparse
                exit
         end
         #Print options if debug is on
         @options.inspect if @options[:debug]
     end

     #Run your code
     def execute
         #Do something
         @options[:name].each{|n| puts "hello #{n}" }
     end
end #End of Class Test

#Include code below so that we can run SayHello through command line
if __FILE__ == $0
    cls = SayHello.new(ARGV)
    cls.execute
end

Now, as shown below,  we can run the SayHello class either through command line or call it through another class. Also, the configuration parameters are handled in the same way.

ruby SayHello.rb --debug --name PersonA,PersonB,PersonC

Through Another Class

SayHello.new("--debug --name PersonA,PersonB,PersonC")