Подтвердить что ты не робот

Вызов Ruby Method, объявленный в классе

Я только что начал изучать рубины на рельсах, и я столкнулся с кодом, как показано ниже:

class Post < ActiveRecord::Base
 validates_presence_of   :title
 belongs_to :user
end

Внутри тела класса есть два вызова метода. Мне было трудно найти какую-либо рубиновую документацию, которая описывает, как работают вызовы методов внутри тела класса (но вне любого метода). Все книги, которые у меня есть, описывают только способы определения методов класса и экземпляра, а также назовите их из других методов.

У меня есть следующие вопросы: Как и когда эти методы называются? Как они определяются? Являются ли они миксинами, определенными в каком-либо активном модуле записи?

4b9b3361

Ответ 1

Тело определения класса - это контекст выполнения для кода, как и любой другой. Код выполняется в контексте класса (значение self - это объект класса, который является экземпляром класса). Вы можете иметь локальные переменные и переменные экземпляра (которые будут принадлежать самому объекту класса, а не экземплярам класса), и вы можете вызвать любой метод, на который отвечает объект класса. Код запускается после завершения блока определения класса.

В этом случае ActiveRecord:: Base определяет методы класса validates_presence_of и belongs_to.

Ответ 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

Описывает, как можно писать такие методы плагина/класса. Это хороший документ о том, как обернуть голову вокруг того, что означают эти типы методов и как они взаимодействуют с экземплярами.