Appels de méthode Ruby déclarés dans le corps de la classe

Je viens de commencer à apprendre le rbuy sur rails et j’ai rencontré le code ci-dessous:

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

Il y a deux appels de méthodes dans le corps de la classe. J’ai eu du mal à trouver une documentation Ruby décrivant le fonctionnement des appels de méthodes dans un corps de classe (mais en dehors de toute méthode). Tous les livres que j’ai, décrivent seulement comment définir les méthodes de classe et d’instance et comment les appeler à partir d’autres méthodes.

Les questions que j’ai sont: comment et quand ces méthodes sont appelées? Comment sont-ils définis? Sont-ils mixins définis dans un module d’enregistrement actif?

Le corps d’une définition de classe est un contexte d’exécution pour le code, comme pour tout autre. Le code est exécuté dans le contexte de la classe (ce self signifie que self est l’object de classe, qui est une instance de Class). Vous pouvez avoir des variables locales et d’instance (qui appartiendront à l’object de classe lui-même plutôt qu’aux instances de la classe) et vous pouvez appeler toute méthode à laquelle l’object de classe répond. Le code est exécuté une fois le bloc de définition de classe terminé.

Dans ce cas, ActiveRecord :: Base définit les méthodes de classe validates_presence_of et belongs_to .

Yehuda Katz a une bonne explication de ceci sur son blog. Voir le point 4: Les corps de classe ne sont pas spéciaux .

Re: Comment et quand ces méthodes sont-elles appelées?

[Ils sont appelés lorsque la classe est chargée. Vous pouvez placer un point d’arrêt dans l’une des méthodes et voir qu’il est appelé dans le cadre du démarrage de votre projet rails.]

Comment sont-ils définis?

[Ils sont des méthodes de classe. Comme il s’agit de rbuy, ils peuvent être définis de différentes manières.]

Sont-ils mixins définis dans un module d’enregistrement actif?

[Dans ce cas,

validates_presence_of est défini dans vendor / rails / activerecord / lib / active_record / validations.rb

amie_to est défini dans vendor / rails / activerecord / lib / active_record / associations.rb

ActiveRecord est un grand système, qui comprend de nombreux mixins, modules, etc.

Remarque: pour voir où les méthodes sont définies, j’utilise http://www.gotapi.com/rubyrails pour chaque méthode, voir le lien “Afficher la source” au bas de la définition.

]

Ce sont des méthodes de classe ou des méthodes «singleton». Vous devriez vous familiariser avec attr_accessor. Nous pouvons implémenter quelque chose comme ça dans une classe de test.

 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  

Dans l’exemple ci-dessus, nous avons créé la méthode de classe avec ‘def self.add_getter_and_setter’, mais ce n’est pas la seule manière.

 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 

Utiliser l'extension. Module # extend est une méthode qui étend une classe avec des méthodes de classe. De même, la méthode Module # include inclut une classe avec des méthodes d'instance.

 class Klass extend(Module.new do def add_getter_and_setter(symbol) .. end end) end 

Si Klass a déjà été défini, nous pouvons le rouvrir pour append des méthodes de classe

 class Klass end def Klass.add_getter_and_setter(symbol) .. end # or class << Klass def add_getter_and_setter(symbol) .. end end 

Eh bien, ce sont quelques façons dont je sais comment faire cela, donc si vous voyez une syntaxe différente, réalisez simplement que tout est en train de faire la même chose.

Note: dans les rails, une méthode de classe commune que nous utilisons tous est «trouver». Il est exécuté directement à partir de la classe Model.

 person = Person.find(1) # finds a person with id:1 

Ce que vous voyez sont des méthodes de niveau classe pour un object ActiveRecord. Pour écrire vos propres méthodes qui fonctionnent comme cela, vous les écririez en tant que plug-in, puis vous les incluriez dans ActiveRecord en rouvrant la définition de la classe. Le guide Ruby on Rails pour créer un plugin:

http://guides.rubyonrails.org/plugins.html

Couvre comment on pourrait écrire un tel plugin / ces méthodes au niveau de la classe. C’est un bon document sur la façon de comprendre ce que signifient ces méthodes et comment elles interagissent avec les instances.