113 votes

Ce qui est mattr_accessor dans un module de Rails ?

Je ne le trouvais vraiment dans la documentation de Rails, mais il semble que « mattr_accessor » est le corollaire de Module pour « attr_accessor » (getter et setter) dans un rubis normal classe.

Par exemple. dans une classe

Par exemple. dans un module

Cette méthode d’assistance est fournie par ActiveSupport.

186voto

Avdi Points 13086

Les Rails s'étend Ruby avec les deux mattr_accessor (Module d'accesseur) et cattr_accessor (ainsi que d' _reader/_writer versions). Comme Ruby attr_accessor génère des getter/setter pour les instances, cattr/mattr_accessor fournir des getter/setter à la classe ou le module de niveau. Donc:

module Config
  mattr_accessor :hostname
  mattr_accessor :admin_email
end

est l'abréviation de:

module Config
  def self.hostname
    @@hostname
  end
  def self.hostname=(hostname)
    @@hostname = hostname
  end
  def self.admin_email
    @@admin_email
  end
  def self.admin_email=(admin_email)
    @@admin_email = admin_email
  end
end

Les deux versions vous permettent d'accéder au module de variables au niveau de la sorte:

>> Config.hostname = "example.com"
>> Config.admin_email = "admin@example.com"
>> Config.hostname # => "example.com"
>> Config.admin_email # => "admin@example.com"

40voto

Orion Edwards Points 54939

Voici le code source pour cattr_accessor

Et

Voici le code source pour mattr_accessor

Comme vous pouvez le voir, ils sont à peu près identiques.

Pourquoi il y a deux versions différentes? Parfois, vous voulez écrire cattr_accessor dans un module, de sorte que vous pouvez l'utiliser pour la configuration de l'info comme Avdi mentionne.
Toutefois, cattr_accessor ne fonctionne pas dans un module, de sorte qu'ils ont plus ou moins copié le code de travail pour les modules aussi.

En outre, parfois, vous pourriez écrire une méthode de classe dans un module, de sorte que lorsque toute la classe comprend le module, il obtient la méthode de la classe ainsi que toutes les méthodes d'instance. mattr_accessor vous permet également de faire cela.

Cependant, dans le deuxième scénario, c'est un comportement est assez étrange. Observer le code suivant, en particulier la note de l' @@mattr_in_module bits

module MyModule
  mattr_accessor :mattr_in_module
end

class MyClass
  include MyModule
  def self.get_mattr; @@mattr_in_module; end # directly access the class variable
end

MyModule.mattr_in_module = 'foo' # set it on the module
=> "foo"

MyClass.get_mattr # get it out of the class
=> "foo"

class SecondClass
  include MyModule
  def self.get_mattr; @@mattr_in_module; end # again directly access the class variable in a different class
end

SecondClass.get_mattr # get it out of the OTHER class
=> "foo"

-3voto

Bogdan Kulbida Points 85

Je me demande pourquoi réinventer la roue... Étant donné que vous pouvez faire ce qui suit avec ruby natif :

Pour les classes :

Mais je suis d’accord, pour les modules c’est précieux  ;)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X