lib/morph.rb in morph-0.1.3 vs lib/morph.rb in morph-0.1.4

- old
+ new

@@ -1,60 +1,52 @@ module Morph - VERSION = "0.1.3" + VERSION = "0.1.4" def self.included(base) base.extend ClassMethods base.send(:include, InstanceMethods) + base.send(:include, MethodMissing) end module ClassMethods + @@adding_morph_method = false @@morph_methods = {} - def convert_to_morph_method_name label - name = label.downcase.tr('()*',' ').gsub('%','percentage').strip.chomp(':').strip.gsub(/\s/,'_').squeeze('_') - name = '_'+name if name =~ /^\d/ - name + def morph_methods + @@morph_methods.keys.sort end - def morph_accessor symbol - attribute = symbol.to_s - @@morph_methods[attribute] = true - @@morph_methods[attribute+'='] = true - class_eval "attr_accessor :#{attribute}" + def adding_morph_method= true_or_false + @@adding_morph_method = true_or_false end - def morph_methods - @@morph_methods.keys.sort + def class_def name, &block + class_eval { define_method name, &block } end - def remove_method symbol - @@morph_methods.delete symbol.to_s - super - end + protected - def remove_morph_writers - writers = morph_methods.select { |m| m =~ /=\Z/ } - writers.each do |writer| - class_eval "remove_method :#{writer}" + def method_added symbol + @@morph_methods[symbol.to_s] = true if @@adding_morph_method end - end - def print_morph_methods - methods = morph_methods - writers = methods.select { |m| m =~ /=\Z/ } - readers = methods.reject { |m| m =~ /=\Z/ } + def method_removed symbol + @@morph_methods.delete symbol.to_s if @@morph_methods.has_key? symbol.to_s + end - accessors = readers.select { |m| writers.include? "#{m}=" } - readers = readers.reject { |m| accessors.include? m } - writers = writers.reject { |m| accessors.include? m.chomp('=') } + end - attributes = accessors.collect { |attribute| "attr_accessor :#{attribute}\n" } - attributes += readers.collect { |attribute| "attr_reader :#{attribute}\n" } - attributes += writers.collect { |attribute| "attr_writer :#{attribute}\n" } + module MethodMissing + def method_missing symbol, *args + is_writer = symbol.to_s =~ /=\Z/ - attributes.join.chop + if is_writer + morph_method_missing symbol, *args + else + super + end end end module InstanceMethods @@ -80,31 +72,45 @@ def morph attributes, value=nil if attributes.is_a? Hash attributes.each { |a, v| morph(a, v) } else label = attributes - attribute = label.is_a?(String) ? self.class.convert_to_morph_method_name(label) : label + attribute = label.is_a?(String) ? convert_to_morph_method_name(label) : label send("#{attribute}=".to_sym, value) end end - def method_missing symbol, *args - is_writer = symbol.to_s =~ /=\Z/ + protected - if is_writer + def morph_method_missing symbol, *args attribute = symbol.to_s.chomp '=' + if Object.instance_methods.include?(attribute) raise "'#{attribute}' is an instance_method on Object, cannot create accessor methods for '#{attribute}'" - elsif args.size > 0 - value = args[0] - empty_value = (value.nil? or (value.is_a?(String) && value.strip.size == 0)) - unless empty_value - self.class.morph_accessor attribute.to_sym + elsif argument_provided? args + base = self.class + base.adding_morph_method= true + + if block_given? + yield base, attribute + else + base.class_eval "attr_accessor :#{attribute}" send(symbol, *args) end + base.adding_morph_method= false end - else - super end - end + + private + + def argument_provided? args + args.size > 0 && !args[0].nil? && !(args[0].is_a?(String) && args[0].strip.size == 0) + end + + def convert_to_morph_method_name label + name = label.downcase.tr('()*',' ').gsub('%','percentage').strip.chomp(':').strip.gsub(/\s/,'_').squeeze('_') + name = '_'+name if name =~ /^\d/ + name + end + end end