module Main class Base EXIT_SUCCESS = 0 EXIT_FAILURE = 1 EXIT_OK = 42 class << self attribute( 'program' ){ File.basename $0 } attribute( 'name' ){ File.basename $0 } attribute( 'synopsis' ){ Usage.default_synopsis self } attribute( 'description' ) attribute( 'author' ) attribute( 'version' ) attribute( 'logger' ){ STDERR } attribute( 'exit_status' ){ EXIT_SUCCESS } attribute( 'exit_success' ){ EXIT_SUCCESS } attribute( 'exit_failure' ){ EXIT_FAILURE } attribute( 'exit_ok' ){ EXIT_OK } attribute( 'usage' ){ Usage.default_usage self } def new *a, &b obj = allocate obj.__initialize__ obj.instance_eval{ initialize *a, &b } obj end def parameters @parameters ||= Parameter::List[] end def parameter *a, &b parameters << Parameter.new(*a, &b) end def option *a, &b (parameters << Parameter.create(:option, *a, &b)).last end alias_method 'opt', 'option' alias_method 'switch', 'option' def default_options! option 'help', 'h' end def argument *a, &b (parameters << Parameter.create(:argument, *a, &b)).last end alias_method 'arg', 'argument' def keyword *a, &b (parameters << Parameter.create(:keyword, *a, &b)).last end alias_method 'kw', 'keyword' def environment *a, &b (parameters << Parameter.create(:environment, *a, &b)).last end alias_method 'env', 'environment' def run *a, &b define_method 'run' &b end end attribute 'argv' attribute 'env' attribute 'params' attribute 'logger' %w( program name synopsis description author version exit_status exit_success exit_failure exit_ok usage ).each{|a| attribute(a){ self.class.send a}} %w( parameters param ).each do |dst| alias_method "#{ dst }", "params" alias_method "#{ dst }=", "params=" alias_method "#{ dst }?", "params?" end %w( exit_success! exit_failure! exit_ok! ).each do |code| module_eval <<-code def #{ code } *a, &b exit #{ code.chop } end code end %w( debug info warn fatal error ).each do |m| module_eval <<-code def #{ m } *a, &b logger.#{ m } *a, &b end code end def __initialize__ argv = ARGV, env = ENV @argv, @env = argv, env log = self.class.logger @logger = case log when Logger log when IO, StringIO Logger.new log else Logger.new *log end __parse_parameters__ end def __parse_parameters__ self.class.parameters.parse @argv, @env #(@params = []).fields = [] @params = Parameter::Table.new self.class.parameters.each do |p| @params[p.name.to_s] = p end end def __run__ if @params['help'] and @params['help'].given? print usage.to_s exit end begin run rescue Exception => e if SystemExit === e exit_status e.status else fatal{ e } exit_status EXIT_FAILURE if exit_status == EXIT_SUCCESS end end status = Integer(exit_status) rescue(exit_status ? 0 : 1) exit status end def run raise NotImplementedError, 'run not defined' end end end