модуль ActiveRecord::AttributeMethods::Read::ClassMethods
Защищенные методы экземпляра
# File activerecord/lib/active_record/attribute_methods/read.rb, line 27
def define_method_attribute(name)
safe_name = name.unpack('h*'.freeze).first
temp_method = "__temp__#{safe_name}"
ActiveRecord::AttributeMethods::AttrNames.set_name_cache safe_name, name
generated_attribute_methods.module_eval " def #{temp_method}
name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{safe_name}
_read_attribute(name) { |n| missing_attribute(n, caller) }
end
", __FILE__, __LINE__ + 1
generated_attribute_methods.module_eval do
alias_method name, temp_method
undef_method temp_method
end
end Мы хотим генерировать методы через module_eval, а не define_method, потому что define_method медленнее при обращении. Оценка многих подобных методов может использовать больше памяти, так как последовательности инструкций дублируются и кешируются (в MRI). define_method может быть медленнее при обращении, но если вы осторожны с созданием замыкания, то define_method будет потреблять намного меньше памяти.
Но иногда база данных может возвращать столбцы с символами, которые не допускаются в обычных именах методов (например, 'my_column(omg)'). Поэтому для обхода этой проблемы мы сначала определяем метод с идентификатором __temp__, а затем используем alias method, чтобы переименовать его в нужное нам.
Мы также определяем константу для хранения замороженной строки имени атрибута. Использование константы означает, что нам не нужно выделять объект при каждом вызове метода атрибута. Замораживание означает, что он не дублируется при использовании в качестве ключа для @attributes в read_attribute.
© 2004–2018 David Heinemeier Hansson
Licensed under the MIT License.