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