Aquí está la fuente de cattr_accessor
Y
Aquí está la fuente de mattr_accessor
Como puede ver, son prácticamente idénticos.
¿Por qué hay dos versiones diferentes? A veces, desea escribir cattr_accessoren un módulo, por lo que puede usarlo para información de configuración como menciona Avdi .
Sin embargo, cattr_accessorno funciona en un módulo, por lo que más o menos copiaron el código para que funcione también con los módulos.
Además, a veces es posible que desee escribir un método de clase en un módulo, de modo que siempre que una clase incluya el módulo, obtenga ese método de clase, así como todos los métodos de instancia. mattr_accessortambién te permite hacer esto.
Sin embargo, en el segundo escenario, su comportamiento es bastante extraño. Observe el siguiente código, particularmente tenga en cuenta los @@mattr_in_modulebits
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"
mattr_accessorsería una abreviatura de las variables de instancia de clase@variable, pero el código fuente parece revelar que en realidad están configurando / leyendo variables de clase. ¿Podría explicar esta diferencia?