Вызов Ruby Method, объявленный в классе
Я только что начал изучать рубины на рельсах, и я столкнулся с кодом, как показано ниже:
class Post < ActiveRecord::Base
validates_presence_of :title
belongs_to :user
end
Внутри тела класса есть два вызова метода.
Мне было трудно найти какую-либо рубиновую документацию, которая
описывает, как работают вызовы методов внутри тела класса (но вне любого метода).
Все книги, которые у меня есть, описывают только способы определения методов класса и экземпляра, а также
назовите их из других методов.
У меня есть следующие вопросы:
Как и когда эти методы называются?
Как они определяются? Являются ли они миксинами, определенными в каком-либо активном модуле записи?
Ответы
Ответ 1
Тело определения класса - это контекст выполнения для кода, как и любой другой. Код выполняется в контексте класса (значение self
- это объект класса, который является экземпляром класса). Вы можете иметь локальные переменные и переменные экземпляра (которые будут принадлежать самому объекту класса, а не экземплярам класса), и вы можете вызвать любой метод, на который отвечает объект класса. Код запускается после завершения блока определения класса.
В этом случае ActiveRecord:: Base определяет методы класса validates_presence_of
и belongs_to
.
Ответ 2
У Yehuda Katz есть приятное объяснение этому в его блоге. См. Пункт 4: Классные элементы не являются специальными.
Ответ 3
Это методы класса или методы "singleton". Вы должны быть знакомы с attr_accessor. Мы можем реализовать что-то подобное в тестовом классе.
class Klass
def self.add_getter_and_setter(symbol)
module_eval "def #{symbol}; @#{symbol}; end"
module_eval "def #{symbol}=(val); @#{symbol} = val; end"
end
end
class Person < Klass
add_getter_and_setter :name
add_getter_and_setter :phone
end
person = Person.new
person.name = 'John Smith'
person.phone = '555-2344'
person # returns <Person:0x28744 @name="John Smith", @phone="555-2344">
В приведенном выше примере мы создали метод класса с 'def self.add_getter_and_setter', но это не единственный способ.
class Klass
class << self # opens the singleton class
def add_getter_and_setter(symbol) # note we dont specify self as it is already within the context of the singleton class
..
end
end
end
Использование расширения. Модуль # extend - это метод, который расширяет класс с помощью методов класса, а также метод Module # include включает класс с методами экземпляра.
class Klass
extend(Module.new do
def add_getter_and_setter(symbol)
..
end
end)
end
Если Klass уже определен, мы можем повторно открыть его, чтобы добавить методы класса
class Klass
end
def Klass.add_getter_and_setter(symbol)
..
end
# or
class << Klass
def add_getter_and_setter(symbol)
..
end
end
Ну, это несколько способов, которыми я знаю, как это сделать, поэтому, если вы видите другой синтаксис, просто осознайте, что все это делает то же самое.
Примечание: в rails метод общего класса, который мы все используем, - "найти". Он запускается непосредственно из класса Model.
person = Person.find(1) # finds a person with id:1
Ответ 4
Re: Как и когда эти методы называются?
[Они вызывается, когда класс загружен. Вы можете поместить контрольную точку в один из методов и увидеть, что она называется частью запуска вашего проекта рельсов.]
Как они определены?
[Это классные методы. Поскольку это рубин, их можно определить несколькими способами.]
Являются ли они миксинами, определенными в каком-либо активном модуле записи?
[В этом случае
validates_presence_of определяется в
поставщика/рельсы/ActiveRecord/Library/active_record/validations.rb
принадлежит_to определяется в
поставщика/рельсы/ActiveRecord/Library/active_record/associations.rb
ActiveRecord - это большая система, включающая множество микшинов, модулей и т.д.
Обратите внимание, чтобы определить, где определены методы, я использую http://www.gotapi.com/rubyrails для каждого метода, см. ссылку "Показать источник" на нижней части определения.
]
Ответ 5
То, что вы видите, это методы уровня класса для объекта ActiveRecord. Чтобы написать свои собственные методы, которые выполняются так, вы должны записать их как плагин, а затем включить их в ActiveRecord, повторно открыв определение класса. Ruby on Rails ведет к созданию плагина:
http://guides.rubyonrails.org/plugins.html
Описывает, как можно писать такие методы плагина/класса. Это хороший документ о том, как обернуть голову вокруг того, что означают эти типы методов и как они взаимодействуют с экземплярами.