lib/active_model/attribute_methods.rb in activemodel-3.0.7 vs lib/active_model/attribute_methods.rb in activemodel-3.0.8.rc1

- old
+ new

@@ -54,10 +54,12 @@ # Hash keys must be strings. # module AttributeMethods extend ActiveSupport::Concern + COMPILABLE_REGEXP = /^[a-zA-Z_]\w*[!?=]?$/ + module ClassMethods # Defines an "attribute" method (like +inheritance_column+ or +table_name+). # A new (class) method will be created with the given name. If a value is # specified, the new method will return that value (as a string). # Otherwise, the given block will be used to compute the value of the @@ -99,14 +101,17 @@ alias_method :'original_#{name}', :'#{name}' eorb if block_given? sing.send :define_method, name, &block else - if name =~ /^[a-zA-Z_]\w*[!?=]?$/ - sing.class_eval <<-eorb, __FILE__, __LINE__ + 1 - def #{name}; #{value.nil? ? 'nil' : value.to_s.inspect}; end - eorb + # If we can compile the method name, do it. Otherwise use define_method. + # This is an important *optimization*, please don't change it. define_method + # has slower dispatch and consumes more memory. + if name =~ COMPILABLE_REGEXP + sing.class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{name}; #{value.nil? ? 'nil' : value.to_s.inspect}; end + RUBY else value = value.to_s if value sing.send(:define_method, name) { value } end end @@ -225,15 +230,24 @@ undefine_attribute_methods end def alias_attribute(new_name, old_name) attribute_method_matchers.each do |matcher| - module_eval <<-STR, __FILE__, __LINE__ + 1 - def #{matcher.method_name(new_name)}(*args) - send(:'#{matcher.method_name(old_name)}', *args) + matcher_new = matcher.method_name(new_name).to_s + matcher_old = matcher.method_name(old_name).to_s + + if matcher_new =~ COMPILABLE_REGEXP && matcher_old =~ COMPILABLE_REGEXP + module_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{matcher_new}(*args) + send(:#{matcher_old}, *args) + end + RUBY + else + define_method(matcher_new) do |*args| + send(matcher_old, *args) end - STR + end end end # Declares a the attributes that should be prefixed and suffixed by # ActiveModel::AttributeMethods. @@ -269,17 +283,28 @@ if respond_to?(generate_method) send(generate_method, attr_name) else method_name = matcher.method_name(attr_name) - generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1 - if method_defined?(:'#{method_name}') + generated_attribute_methods.module_eval <<-RUBY, __FILE__, __LINE__ + 1 + if method_defined?('#{method_name}') undef :'#{method_name}' end - define_method('#{method_name}') do |*args| - send(:'#{matcher.method_missing_target}', '#{attr_name}', *args) - end - STR + RUBY + + if method_name.to_s =~ COMPILABLE_REGEXP + generated_attribute_methods.module_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{method_name}(*args) + send(:#{matcher.method_missing_target}, '#{attr_name}', *args) + end + RUBY + else + generated_attribute_methods.module_eval <<-RUBY, __FILE__, __LINE__ + 1 + define_method('#{method_name}') do |*args| + send('#{matcher.method_missing_target}', '#{attr_name}', *args) + end + RUBY + end end end end end @attribute_methods_generated = true