lib/woyo/world/attributes.rb in woyo-world-0.0.7 vs lib/woyo/world/attributes.rb in woyo-world-0.0.8

- old
+ new

@@ -6,48 +6,65 @@ module Woyo module Attributes + class AttributesHash < Hash + + alias_method :names, :keys + alias_method :set, :[]= + + attr_reader :listeners + + def initialize + @listeners = {} + end + + def add_attribute_listener attr, listener + @listeners[attr] = listener + end + + def []= attr, value + old_value = self[attr] + super + if ( listener = @listeners[attr] ) && value != old_value + listener.notify attr, value + end + end + + end + def attribute *attrs, &block - send :_attributes, attrs, ivn: '@attributes', &block + attributes *attrs, &block end def attributes *attrs, &block - send :_attributes, attrs, ivn: '@attributes', &block - end - - def _attributes attrs, ivn:, &block - if instance_variable_defined? ivn - ivar = instance_variable_get ivn - else - ivar = instance_variable_set ivn, Woyo::Attributes::AttributesHash.new - end - return ivar if attrs.empty? + @attributes ||= Woyo::Attributes::AttributesHash.new + return @attributes if attrs.empty? attrs.each do |attr| case when attr.kind_of?( Hash ) attr.each do |attr_sym,default| - define_attr_methods attr_sym, default, ivn: ivn - ivar[attr_sym] = send "#{attr_sym}_default" + define_attr_methods attr_sym, default + @attributes[attr_sym] = send "#{attr_sym}_default" end when block - define_attr_methods attr, block, ivn: ivn - ivar[attr] = send "#{attr}_default" + define_attr_methods attr, block + @attributes[attr] = send "#{attr}_default" else - unless ivar.include? attr - define_attr_methods attr, ivn: ivn - ivar[attr] = nil + unless @attributes.include? attr + define_attr_methods attr + @attributes[attr] = nil end end end end - def define_attr_methods( attr, default = nil, ivn: ) + def define_attr_methods attr, default = nil define_attr_default attr, default - define_attr_equals attr, ivn: ivn - define_attr attr, ivn: ivn + define_attr_equals attr + define_attr attr if default == true || default == false # boolean convenience methods define_attr? attr define_attr! attr end end @@ -56,30 +73,35 @@ define_singleton_method "#{attr}_default" do default end end - def define_attr_equals( attr, ivn: ) + def define_attr_equals attr define_singleton_method "#{attr}=" do |arg| - ivar = instance_variable_get ivn - ivar[attr] = arg + @attributes[attr] = arg end end - def define_attr( attr, ivn: ) + def define_attr attr define_singleton_method attr do |arg = nil| - ivar = instance_variable_get ivn - return ivar[attr] = arg unless arg.nil? + return @attributes[attr] = arg unless arg.nil? case - when ivar[attr].kind_of?( Hash ) - true_attribute_match = ivar[attr].detect { |name,value| ivar[name] == true } - return true_attribute_match[1] if true_attribute_match - ivar[attr] - when ivar[attr].respond_to?( :call ) - return ivar[attr].arity == 0 ? ivar[attr].call : ivar[attr].call(self) + when @attributes[attr].kind_of?( Hash ) + truthy_matches = @attributes[attr].collect do |name,value| + truthy = if @attributes[name].respond_to?( :call ) + @attributes[name].arity == 0 ? @attributes[name].call : @attributes[name].call(self) + else + @attributes[name] + end + truthy ? value : nil + end.compact + truthy_matches = truthy_matches.count == 1 ? truthy_matches[0] : truthy_matches + return truthy_matches + when @attributes[attr].respond_to?( :call ) + return @attributes[attr].arity == 0 ? @attributes[attr].call : @attributes[attr].call(self) else - ivar[attr] + @attributes[attr] end end end def define_attr? attr @@ -98,57 +120,9 @@ send "#{attr}?" end def is attr send "#{attr}=", true - end - - def groups - @groups - end - - def group sym, *attrs - @groups ||= {} - grp = @groups[sym] ? @groups[sym] : ( @groups[sym] = Woyo::Attributes::Group.new attributes ) - attributes *attrs - attrs.each do |attr| - if attr.kind_of? Hash - attr.each do |attr_sym,default_value| - grp << attr_sym - end - else - grp << attr - end - end - define_singleton_method sym do - @groups[sym] - end - grp - end - - def exclusions - @exclusions - end - - def exclusion sym, *attrs - @exclusions ||= {} - exc = @exclusions[sym] ? @exclusions[sym] : ( @exclusions[sym] = Woyo::Attributes::Exclusion.new attributes ) - attributes *attrs - attrs.each do |attr| - define_attr? attr - define_attr! attr - if attr.kind_of? Hash - attr.each do |attr_sym,default_value| - exc << attr_sym - end - else - exc << attr - end - end - define_singleton_method sym do - @exclusions[sym] - end - exc end end end