lib/innate/traited.rb in manveru-innate-2009.04.18 vs lib/innate/traited.rb in manveru-innate-2009.05

- old
+ new

@@ -24,20 +24,23 @@ # Foo.trait[:hello] # => "Hello" # foo = Foo.new # foo.trait[:hello] # => "World!" # foo.show # => ["Hello", "World!", "World!"] module Traited - TRAITS = {} + TRAITS, ANCESTRAL_TRAITS, ANCESTRAL_VALUES = {}, {}, {} def self.included(into) into.extend(self) end def trait(hash = nil) if hash TRAITS[self] ||= {} - TRAITS[self].merge!(hash) + result = TRAITS[self].merge!(hash) + ANCESTRAL_VALUES.clear + ANCESTRAL_TRAITS.clear + result else TRAITS[self] || {} end end @@ -58,24 +61,26 @@ # end # # Foobar.ancestral_trait # # => {:three => :drei, :two => :zwei, :one => :eins, :first => :overwritten} def ancestral_trait - result = {} - each_ancestral_trait{|trait| result.merge!(trait) } - result + klass = self.kind_of?(Module) ? self : self.class + ANCESTRAL_TRAITS[klass] ||= + each_ancestral_trait({}){|hash, trait| hash.update(trait) } end def ancestral_trait_values(key) - result = [] - each_ancestral_trait{|trait| result << trait[key] if trait.key?(key) } - result + klass = self.kind_of?(Module) ? self : self.class + cache = ANCESTRAL_VALUES[klass] ||= {} + cache[key] ||= each_ancestral_trait([]){|array, trait| + array << trait[key] if trait.key?(key) } end - def each_ancestral_trait + def each_ancestral_trait(obj) ancs = respond_to?(:ancestors) ? ancestors : self.class.ancestors ancs.unshift(self) - ancs.reverse_each{|anc| yield(TRAITS[anc]) if TRAITS.key?(anc) } + ancs.reverse_each{|anc| yield(obj, TRAITS[anc]) if TRAITS.key?(anc) } + obj end # trait for self.class if we are an instance def class_trait respond_to?(:ancestors) ? trait : self.class.trait