Spec-Zone.ru › Ruby on Rails 5.0

модуль ActiveRecord::AttributeMethods::Read::ClassMethods

Защищенные методы экземпляра

define_method_attribute(name) Показать исходный код
# 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.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API