# $Id$ # Equivalent to a header guard in C/C++ # Used to prevent the class/module from being loaded more than once unless defined? CkuruTools class Module def instance_of_class_accessor( klass, *symbols ) symbols.each do |symbol| module_eval( "def #{symbol}() @#{symbol}; end" ) module_eval( "def #{symbol}=(val) raise ArgumentError.new('#{symbol} must be a #{klass}, not one of ' + val.class.ancestors.to_s) unless val.class.inherits_from? #{klass} ; @#{symbol} = val; self.send(:after_#{symbol}_set) if self.respond_to?(:after_#{symbol}_set); end" ) end end def class_accessor( klass, *symbols ) symbols.each do |symbol| module_eval( "def #{symbol}() @#{symbol}; end" ) module_eval( " def #{symbol}=(val) raise ArgumentError.new('argument to #{symbol} must be a class') unless val.is_a? Class raise ArgumentError.new('#{symbol} must be a #{klass}') unless val.inherits_from? #{klass} @#{symbol} = val end" ) end end # raise ArgumentError.new("assignment must be of class CkuruTools::TypedArray, not \#{arr.class}") unless arr.instance_inherits_from? CkuruTools::TypedArray # raise ArgumentError.new("TypedArray must require #{klass}") unless arr.required_type == #{klass} def typed_array_accessor(klass,*symbols) symbols.each do |symbol| module_eval( "def #{symbol}() @#{symbol}; end" ) module_eval <<"EOF" def #{symbol}=(arr) @#{symbol} = CkuruTools::TypedArray.new(#{klass}) arr.each do |elem| @#{symbol}.push elem end @#{symbol} end EOF end end end module CkuruTools def self.parameters(h,*args) raise ArgumentError.new("argument to #{self.class}##{current_method} must be of class Hash; you may get this error if you don't call a function with a hash; check the initial call") unless h.is_a? Hash ret = [] args.each do |a| name,options = a options = options || {} unless h[:no_recurse] vals = only_these_parameters( options.merge!(:no_recurse => true), [:instance_that_inherits_from, {:instance_of => Class}], [:instance_of, {:instance_of => Class}], [:klass_that_inherits_from, {:instance_of => Class}], [:klass_of, {:instance_of => Class}], [:no_recurse, {:instance_of => TrueClass}], [:required, {:instance_of => TrueClass}], [:default, {:instance_of => TrueClass}] ) instance_that_inherits_from, instance_of, klass_that_inherits_from, klass_of, no_recurse, required, default = vals end if val = h[name] if instance_that_inherits_from unless val.class.inherits_from? instance_that_inherits_from raise ArgumentError.new( "argument :#{name} to #{self.class}##{calling_method} must be an instance that inherits from #{instance_that_inherits_from}, #{val.class} does not") end elsif instance_of unless val.class == instance_of raise ArgumentError.new( "argument :#{name} to #{self.class}##{calling_method} must be an instance of class #{instance_of}, not #{val.class}") end elsif klass_that_inherits_from unless val.inherits_from? klass_that_inherits_from raise ArgumentError.new("argument :#{name} to #{self.class}##{calling_method} must inherits from class #{klass_that_inherits_from}, #{val} does not") end elsif klass_of unless val == klass_to raise ArgumentError.new("argument :#{name} to #{self.class}##{calling_method} must be of class #{klass_of}, not #{val}") end end else if options[:default] val = options[:default] elsif options[:required] raise ArgumentError.new("argument :#{name} to #{self.class}##{calling_method} is required") end end ret.push val end ret end def self.only_these_parameters(h,*args) ret = parameters(h,*args) keys = h.keys args.each do |a| name,options = a keys.delete name end if keys.length > 0 raise ArgumentError.new("unknown parameters #{keys.inspect} passed to #{self.class}##{calling_method}") end ret end def self.validate_hash_arguments(h,*args) raise ArgumentError.new("argument to #{current_method} must be of class Hash") unless h.is_a? Hash ret = [] args.each do |a| name,options = a options = options || {} unless h[:no_recurse] vals = only_these_parameters( options.merge!(:no_recurse => true), [:instance_that_inherits_from, {:instance_of => Class}], [:instance_of, {:instance_of => Class}], [:klass_that_inherits_from, {:instance_of => Class}], [:klass_of, {:instance_of => Class}], [:no_recurse, {:instance_of => TrueClass}], [:required, {:instance_of => TrueClass}], [:default, {:instance_of => TrueClass}] ) instance_that_inherits_from, instance_of, klass_that_inherits_from, klass_of, no_recurse, required, default = vals end if val = h[name] if instance_that_inherits_from unless val.class.inherits_from? instance_that_inherits_from raise ArgumentError.new( "argument :#{name} to #{calling_method} must be an instance that inherits from #{instance_that_inherits_from}, #{val.class} does not") end elsif instance_of unless val.class == instance_of raise ArgumentError.new( "argument :#{name} to #{calling_method} must be an instance of class #{instance_of}, not #{val.class}") end elsif klass_that_inherits_from unless val.inherits_from? klass_that_inherits_from raise ArgumentError.new("argument :#{name} to #{calling_method} must inherits from class #{klass_that_inherits_from}, #{val} does not") end elsif klass_of unless val == klass_of raise ArgumentError.new("argument :#{name} to #{calling_method} must be of class #{klass_of}, not #{val}") end end else if options[:default] val = options[:default] elsif options[:required] raise ArgumentError.new("argument :#{name} to #{calling_method} is required") end end ret.push val end ret end def self.class_space ret = TypedArray.new(Class) ObjectSpace.each_object {|x| ret.push(x) if x.is_a? Class} ret.uniq end # :stopdoc: LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR # :startdoc: # Returns the version string for the library. # def self.version VERSION end # Returns the library path for the module. If any arguments are given, # they will be joined to the end of the libray path using # File.join. # def self.libpath( *args ) args.empty? ? LIBPATH : ::File.join(LIBPATH, *args) end # Returns the lpath for the module. If any arguments are given, # they will be joined to the end of the path using # File.join. # def self.path( *args ) args.empty? ? PATH : ::File.join(PATH, *args) end # Utility method used to rquire all files ending in .rb that lie in the # directory below this file that has the same name as the filename passed # in. Optionally, a specific _directory_ name can be passed in such that # the _filename_ does not have to be equivalent to the directory. # def self.require_all_libs_relative_to( fname, dir = nil ) dir ||= ::File.basename(fname, '.*') search_me = ::File.expand_path( ::File.join(::File.dirname(fname), dir, '**', '*.rb')) Dir.glob(search_me).sort.each {|rb| require rb} end # # extending HashInitalizerClass enables you to get Object.new(hash) functionality # where each key will dispatch to an object setter method. # # Usage: # # class MyClass < HashInitalizerClass # ..attr_accessor :foo # end # # m = MyClass(:foo => "bar") # m.foo # => "bar" # # class HashInitializerClass # check for required attributes def required_attributes(*symbols) symbols.each do |symbol| raise ArgumentError.new("attribute :#{symbol} must be set in #{self.class}.initialize") if self.send(symbol).nil? end end # parse and return parameters from a hash # # view = only_these_parameters(h,[:view,{:klass => View,:required => true}]) # or # # view = parameters(h,[:view,{:klass => View,:required => true}]) def parameters(h,*args) CkuruTools.parameters(h,args) end # insure that only the defined parameters have been passed to a function def only_these_parameters(h,*args) CkuruTools.only_these_parameters(h,args) end def initialize(h={}) raise ArgumentError.new("argument to #{self.class}##{current_method} must be of class Hash") unless h.is_a? Hash h.keys.each do |k| self.send("#{k}=",h[k]) end yield self if block_given? end end end # module CkuruTools CkuruTools.require_all_libs_relative_to __FILE__ CkuruTools.require_all_libs_relative_to CkuruTools.libpath # # class Foo < ActiveRecord::Base # end # # Foo.inherits_from? ActiveRecord::Base # => true # class Class # show's live decendants of this class def decendants CkuruTools.class_space.select {|x| x.inherits_from? self and x != self} end def inherits_from?(klass) raise ArgumentError.new("argument must be of type Class") unless klass.is_a? Class if klass == self true elsif self.superclass.is_a? Class self.superclass.inherits_from? klass else false end end end class Array def to_comma_separated_string ret = '' self.each do |elem| ret += ',' if ret.length > 0 ret += elem.to_s end ret end end class Object # this method allows a an 'initialize' method to define itself as a abstract class; yet still run some code. # # To use effectively place at the last line of an initialize method like so: # # class DataSource < ::CkuruTools::HashInitializerClass # def initialize(h={}) # super h # this_is_an_abstract_constructor_for AuraVisualize::DataSource # end # end def this_is_an_abstract_constructor_for(klass) unless self.class.superclass.inherits_from? klass # abstract constructor str = '' self.class.decendants.each do |d| str += "#{d}\n" end raise <<"EOF" Do not call method of #{self.class}.#{calling_method} directly, you must instantiate a base class. Maybe you want one of these?: #{str} EOF end end # see if this object's class inherits from another class def instance_inherits_from?(klass) self.class.inherits_from?(klass) end def _require ; each {|r| require r } ; end def docmd(cmd,dir=nil) ret = docmdi(cmd,dir) if ret.exitstatus != 0 raise "cmd #{cmd} exitstatus #{ret.exitstatus} : #{ret}" end ret end def docmdi(cmd,dir=nil) if dir unless Dir.chdir(dir) ckebug 0, "failed to cd to #{dir}" return nil end end ret = msg_exec "running #{cmd}" do cmd.gsub!(/\\/,"\\\\\\\\\\\\\\\\") cmd.gsub!(/\'/,"\\\\'") cmd.gsub!(/\"/,"\\\\\\\\\\\"") system("bash -c \"#{cmd}\"") if $?.exitstatus != 0 print " ** failed ** exit code #{$?.exitstatus} " end end $? end ################################################################################ def docmd_dir(h={}) ret = nil if h[:dir] unless Dir.chdir(h[:dir]) ckebug 0, "failed to cd to #{h[:dir]}" return nil end end if h[:commands] h[:commands].each do |cmd| ret = docmd(cmd) if ret.exitstatus != 0 ckebug 0, "giving up" return ret end end end ret end def emacs_trace begin yield rescue Exception => e puts e puts "... exception thrown from ..." e.backtrace.each do |trace| a = trace.split(/:/) if a[0].match(/^\//) puts "#{a[0]}:#{a[1]}: #{a[2..a.length].join(':')}" else d = File.dirname(a[0]) f = File.basename(a[0]) dir = `cd #{d}; pwd`.chomp goodpath = File.join(dir,f) puts "#{goodpath}:#{a[1]}: #{a[2..a.length].join(':')}" end if $emacs_trace_debugger require 'ruby-debug' end end raise "sorry ...exiting" end end def ckebug(level,msg) CkuruTools::Debug.instance.debug(level,msg) end def current_method caller[0].match(/`(.*?)'/)[1] end def calling_method caller[1] ? caller[1].match(/`(.*?)'/)[1] : "" end def calling_method2 if caller[2] if matchdata = caller[2].match(/`(.*?)'/) matchdata[1] else "" end else "" end end def calling_method3 if caller[3] if matchdata = caller[3].match(/`(.*?)'/) matchdata[2] else "" end else "" end end def calling_method_sig caller[1] ? caller[1] : "" end # def calling_method # if caller[2] # caller[2].match(/`(.*?)'/)[1] # else # "" # end # end end end class Time def ckuru_time_string strftime("%m/%d/%Y %H;%M;%S") end end def printmsg(msg,newline=true) print "#{Time.new.ckuru_time_string}: #{msg}" puts if newline end #module MlImportUtils def msg_exec(msg) printmsg("#{msg} ... ",false) t1 = Time.new ret = yield puts "done (#{Time.new - t1})" ret end def chatty_exec(level,name) ret = yield ckebug level, "#{name} is #{ret}" ret end # EOF