class Object def singleton_method_added(*a, &b) #{{{ obj = self obj.__trait_singleton_class.module_eval{ @__trait_singleton_super = obj } #}}} end def __trait_singleton_class #{{{ @__trait_singleton_class ||= class << self;self;end #}}} end def __trait_singleton? #{{{ @__is_trait_singleton ||= ((Class === self) and (@__is_trait_singleton ||= (not self.ancestors.include?(self)))) #}}} end def __trait_search_path #--{{{ #((Class === self and not __trait_singleton?) ? ancestors : [self]) (__trait_singleton? or not respond_to? 'ancestors') ? [self] : ancestors #--}}} end def __trait_arg_filter(*args) #--{{{ args, hashes = [ args ].flatten.partition{|item| not Hash === item} opts = hashes.inject(accum={}){|accum,hash| accum.update hash} [ args, opts ] #--}}} end def __trait_instance_method_list #--{{{ @__trait_instance_method_list ||= {'writers' => [], 'readers' => []} #--}}} end def __trait_singleton_method_list #--{{{ @__trait_singleton_method_list ||= {'writers' => [], 'readers' => []} #--}}} end def __trait_instance_method_defaults #--{{{ @__trait_instance_method_defaults ||= {} #--}}} end def __trait_singleton_method_defaults #--{{{ @__trait_singleton_method_defaults ||= {} #--}}} end def __trait_define_singleton_reader_traits(*args) #--{{{ names, names_and_defaults = __trait_arg_filter args names.each{|name| names_and_defaults[name] = nil} defaults = __trait_singleton_method_defaults list = __trait_singleton_method_list unless names_and_defaults.empty? names_and_defaults.each do |name, default| __trait_singleton_class.__trait_define_reader_trait name, default, defaults, list end end __trait_search_path.map{|ta| ta.__trait_singleton_method_list['readers']}.flatten #--}}} end def __trait_define_singleton_writer_traits(*args) #--{{{ names, names_and_defaults = __trait_arg_filter args names.each{|name| names_and_defaults[name] = nil} defaults = __trait_singleton_method_defaults list = __trait_singleton_method_list unless names_and_defaults.empty? names_and_defaults.each do |name, default| __trait_singleton_class.__trait_define_writer_trait name, default, defaults, list end end __trait_search_path.map{|ta| ta.__trait_singleton_method_list['writers']}.flatten #--}}} end def __trait_define_singleton_traits(*args) #--{{{ writers = __trait_define_singleton_writer_traits(*args) readers = __trait_define_singleton_reader_traits(*args) [readers, writers] #--}}} end end class Class def __trait_singleton_super class_eval{ def __________trait_singleton_super_init;end } unless defined? @__trait_singleton_super @__trait_singleton_super end end class Module #--{{{ def __trait_define_instance_reader_traits(*args) #--{{{ if __trait_singleton? return(__trait_singleton_super.__trait_define_singleton_reader_traits(*args)) end names, names_and_defaults = __trait_arg_filter args names.each{|name| names_and_defaults[name] = nil} defaults = __trait_instance_method_defaults list = __trait_instance_method_list unless names_and_defaults.empty? names_and_defaults.each do |name, default| __trait_define_reader_trait name, default, defaults, list end end __trait_search_path.map{|ta| ta.__trait_instance_method_list['readers']}.flatten #--}}} end %w( instance_reader_traits instance_reader_trait reader_traits reader_trait rtraits rtrait has_readers has_reader has_r ).each{|meth| alias_method meth, '__trait_define_instance_reader_traits'} def __trait_define_instance_writer_traits(*args) #--{{{ if __trait_singleton? return(__trait_singleton_super.__trait_define_singleton_writer_traits(*args)) end names, names_and_defaults = __trait_arg_filter args names.each{|name| names_and_defaults[name] = nil} defaults = __trait_instance_method_defaults list = __trait_instance_method_list unless names_and_defaults.empty? names_and_defaults.each do |name, default| __trait_define_writer_trait name, default, defaults, list end end __trait_search_path.map{|ta| ta.__trait_instance_method_list['writers']}.flatten #--}}} end %w( instance_writer_traits instance_writer_trait writer_traits writer_trait wtraits wtrait has_writers has_writer has_w ).each{|meth| alias_method meth, '__trait_define_instance_writer_traits'} def __trait_define_instance_traits(*args) #--{{{ writers = __trait_define_instance_writer_traits(*args) readers = __trait_define_instance_reader_traits(*args) [readers, writers] #--}}} end %w( instance_traits instance_trait traits trait has ).each{|meth| alias_method meth, '__trait_define_instance_traits'} def __trait_define_class_reader_traits(*args) #--{{{ __trait_define_singleton_reader_traits(*args) #--}}} end %w( class_reader_traits class_reader_trait class_rtraits class_rtrait class_has_readers class_has_reader class_has_r c_has_readers c_has_reader c_has_r ).each{|meth| alias_method meth, '__trait_define_class_reader_traits'} def __trait_define_class_writer_traits(*args) #--{{{ __trait_define_singleton_writer_traits(*args) #--}}} end %w( class_writer_traits class_writer_trait class_wtraits class_wtrait class_has_writers class_has_writer class_has_w c_has_writers c_has_writer c_has_w ).each{|meth| alias_method meth, '__trait_define_class_writer_traits'} def __trait_define_class_traits(*args) #--{{{ __trait_define_singleton_traits(*args) #--}}} end %w( class_traits class_trait class_has c_has ).each{|meth| alias_method meth, '__trait_define_class_traits'} def __trait_define_reader_trait name, default, defaults, list #{{{ getter = "#{ name }" setter = "#{ name }=" query = "#{ name }?" defaults[getter] = default if default list['readers'] << getter unless instance_methods.include? getter code = __trait_gen_reader_code name, 'public' module_eval code end unless instance_methods.include? setter code = __trait_gen_writer_code name, 'private' module_eval code end unless instance_methods.include? query code = __trait_gen_query_code name, 'public' module_eval code end #}}} end def __trait_define_writer_trait name, default, defaults, list #{{{ reader = "#{ name }" writer = "#{ name }=" query = "#{ name }?" defaults[reader] = default if default list['writers'] << writer unless instance_methods.include? reader code = __trait_gen_reader_code name, 'private' module_eval code end unless instance_methods.include? writer code = __trait_gen_writer_code name, 'public' module_eval code end unless instance_methods.include? query code = __trait_gen_query_code name, 'private' module_eval code end #}}} end def __trait_gen_reader_code name, access_protection = 'public' #--{{{ s = __trait_singleton? #&& __trait_singleton_super.is_a?(Class) klass = s ? 'self' : 'self.class' defaults = s ? '__trait_singleton_method_defaults' : '__trait_instance_method_defaults' search_ancestors = s ? 'true' : 'false' getter_meth = "#{ name }" setter_meth = "#{ name }=" query_meth = "#{ name }?" ivar = "@#{ name }" getter = "'#{ name }'" setter = "'#{ name }='" reader_code = <<-code def #{ name }(*a, &b) unless a.empty? send('#{ name }=', *a, &b) else unless(defined?(@________#{ name }_set) and @________#{ name }_set) #{ klass }.__trait_search_path.each do |obj| #if self != obj and obj.respond_to? '#{ name }' #return(obj.send('#{ name }', *a, &b)) #else defaults = obj.#{ defaults } return(send('#{ name }=', *defaults['#{ name }'])) if defaults.has_key? '#{ name }' #end end end case self when Class if defined? @#{ name } @#{ name } else __trait_search_path.each do |obj| if self != obj and obj.respond_to? '#{ name }' return(obj.send('#{ name }', *a, &b)) end end return nil end else @#{ name } end end end #{ access_protection } '#{ name }'.intern code #p self #puts reader_code #reader_code #--}}} end def __trait_gen_writer_code name, access_protection = 'public' #--{{{ writer_code = <<-code def #{ name }= value @________#{ name }_set = true @#{ name } = value end #{ access_protection } '#{ name }='.intern code #--}}} end def __trait_gen_query_code name, access_protection = 'public' #--{{{ query_code = <<-code def #{ name }? send('#{ name }') ? true : false end # #{ access_protection } '#{ name }?'.intern code #p self #puts query_code #query_code #--}}} end def __trait_gen_access_protection_code name, access_protection = nil #--{{{ access_protection ||= 'public' case access_protection when %r/private/ "private '#{ name }'.intern" when %r/protected/ "protected '#{ name }'.intern" else "public '#{ name }'.intern" end #--}}} end #--}}} end