1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

method transplanting between modules isn't supported on 1.9

This commit is contained in:
Aaron Patterson 2013-07-03 14:18:31 -07:00
parent a593fc1ee1
commit b785e921d1
3 changed files with 62 additions and 10 deletions

View file

@ -1,3 +1,5 @@
require 'active_support/core_ext/module/method_transplanting'
module ActiveRecord
module AttributeMethods
module Read
@ -62,9 +64,30 @@ module ActiveRecord
protected
def define_method_attribute(name)
method = ReaderMethodCache[name]
generated_attribute_methods.module_eval { define_method name, method }
if Module.methods_transplantable?
def define_method_attribute(name)
method = ReaderMethodCache[name]
generated_attribute_methods.module_eval { define_method name, method }
end
else
def define_method_attribute(name)
safe_name = name.unpack('h*').first
temp_method = "__temp__#{safe_name}"
ActiveRecord::AttributeMethods::AttrNames.set_name_cache safe_name, name
generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
def #{temp_method}
name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{safe_name}
read_attribute(name) { |n| missing_attribute(n, caller) }
end
STR
generated_attribute_methods.module_eval do
alias_method name, temp_method
undef_method temp_method
end
end
end
private

View file

@ -1,3 +1,5 @@
require 'active_support/core_ext/module/method_transplanting'
module ActiveRecord
module AttributeMethods
module Write
@ -23,13 +25,29 @@ module ActiveRecord
module ClassMethods
protected
# See define_method_attribute in read.rb for an explanation of
# this code.
def define_method_attribute=(name)
method = WriterMethodCache[name]
generated_attribute_methods.module_eval {
define_method "#{name}=", method
}
if Module.methods_transplantable?
# See define_method_attribute in read.rb for an explanation of
# this code.
def define_method_attribute=(name)
method = WriterMethodCache[name]
generated_attribute_methods.module_eval {
define_method "#{name}=", method
}
end
else
def define_method_attribute=(name)
safe_name = name.unpack('h*').first
ActiveRecord::AttributeMethods::AttrNames.set_name_cache safe_name, name
generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
def __temp__#{safe_name}=(value)
name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{safe_name}
write_attribute(name, value)
end
alias_method #{(name + '=').inspect}, :__temp__#{safe_name}=
undef_method :__temp__#{safe_name}=
STR
end
end
end

View file

@ -0,0 +1,11 @@
class Module
###
# TODO: remove this after 1.9 support is dropped
def methods_transplantable? # :nodoc:
x = Module.new { def foo; end }
Module.new { define_method :bar, x.instance_method(:foo) }
true
rescue TypeError
false
end
end