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