require 'cgi' # trying to make cgi.rb suck a tad bit less. # the main thing I care about is clean, error-free parameter input. # brendan o'connor (brenocon@gmail.com) class MyCGI < CGI def initialize super("html3") @converted_opts = {} end def opt name, opts={} self.class.send :define_method, name.to_sym do @converted_opts[name.to_sym] end # if opts[:default].andand.is_a? Array @converted_opts[name.to_sym] = get(name, opts) end # def method_missing(msg, *args) # @converted_opts[msg] || get(msg) # end def get(k, opts={}) k=k.to_s if params.keys.include?(k) type_convert k, params[k][0], opts else opts[:default] end end TYPES = [:boolean, :bool, :int, :integer, :string, :double, :float] FLOAT_RE = /^-?((\d+(\.\d+)?)|(\.\d+))$/ def type_convert(name, value, opts) # stolen from Trollop, the one true Ruby commandline option parser. opts[:type] = case opts[:type] when :boolean, :bool; :bool when :int, :integer; :int when :string; :string when :double, :float; :float when Class case opts[:type].to_s # sigh... there must be a better way to do this when 'TrueClass', 'FalseClass'; :bool when 'String'; :string when 'Integer'; :int when 'Float'; :float else raise ArgumentError, "unsupported argument type '#{opts[:type].class.name}'" end when nil; nil else raise ArgumentError, "unsupported argument type '#{opts[:type]}'" unless TYPES.include?(opts[:type]) end type_from_default = case opts[:default] when Integer; :int when Numeric; :float when TrueClass, FalseClass; :bool when String; :string when nil; nil else raise ArgumentError, "unsupported argument type '#{opts[:default].class.name}'" end raise ArgumentError, ":type specification and default type don't match" if opts[:type] && type_from_default && opts[:type] != type_from_default # opts[:type] = (opts[:type] || type_from_default || raise("Need :type or :default for every param!")) opts[:type] = (opts[:type] || type_from_default || :string) return opts[:default] if value.blank? case opts[:type] when :bool value=='y' ? true : value=='n' ? false : raise("option '#{name}' needs a boolean-coercible value, but got #{value.inspect}") when :int raise "option '#{name}' needs an integer but got #{value.inspect}" unless value =~ /^\d+$/ value.to_i when :float raise CommandlineError, "option '#{name}' needs a floating-point number but got #{value.inspect}" unless value =~ FLOAT_RE value.to_f when :string value.to_s else raise("oops") end end end class String def blank? self =~ /^\s*$/ end end class NilClass def blank? true end end def prepp(o) puts "
"
  require 'pp'
  begin
    puts o.pretty_print_inspect.gsub(">",">").gsub("<","<")
  rescue
    pp o
  end
  puts "
" end