Qu'est-ce que mattr accessor dans un module Rails?
Je ne pouvais pas vraiment trouver cela dans la documentation des Rails, mais il semble que 'mattr_accessor' soit le Module corollaire pour 'attr_accessor' (getter & setter) dans un Ruby normal classe .
par exemple. dans une classe
class User
attr_accessor :name
def set_fullname
@name = "#{self.first_name} #{self.last_name}"
end
end
par exemple. dans un module
module Authentication
mattr_accessor :current_user
def login
@current_user = session[:user_id] || nil
end
end
cette méthode d'aide est fournie par ActiveSupport .
2 réponses
rallonge Ruby avec les versions mattr_accessor
(module accessor) et cattr_accessor
(ainsi que _ reader
/ _writer
). Comme Ruby attr_accessor
génère des méthodes getter/setter pour instances , cattr/mattr_accessor
fournir des méthodes getter/setter au niveau classe ou module . Ainsi:
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 permet d'accéder aux variables au niveau du module comme ceci:
>> Config.hostname = "example.com"
>> Config.admin_email = "admin@example.com"
>> Config.hostname # => "example.com"
>> Config.admin_email # => "admin@example.com"
Voici la source de cattr_accessor
et
Voici la source de 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 les informations de configuration comme Avdi mentionne .
Cependant, cattr_accessor
ne fonctionne pas dans un module, de sorte qu'ils ont plus ou moins copié le code pour travailler pour les modules aussi.
de plus, parfois vous pourriez vouloir écrire une méthode de classe dans un module, de sorte que chaque fois que n'importe quelle classe inclut le module, il obtient cette méthode de classe aussi bien que toutes les méthodes d'instance. mattr_accessor
vous permet également de le faire.
cependant, dans le second scénario, son comportement est assez étrange. Observez le code suivant, en particulier notez le @@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"