I couldn't really find this in Rails documentation but it seems like 'mattr_accessor' is the Module corollary for 'attr_accessor' (getter & setter) in a normal Ruby class.
Eg. in a class
class User
attr_accessor :name
def set_fullname
@name = "#{self.first_name} #{self.last_name}"
end
end
Eg. in a module
module Authentication
mattr_accessor :current_user
def login
@current_user = session[:user_id] || nil
end
end
This helper method is provided by ActiveSupport.
Rails extends Ruby with both
mattr_accessor
(Module accessor) andcattr_accessor
(as well as _reader
/_writer
versions). As Ruby'sattr_accessor
generates getter/setter methods for instances,cattr/mattr_accessor
provide getter/setter methods at the class or module level. Thus:is short for:
Both versions allow you to access the module-level variables like so:
Here's the source for
cattr_accessor
And
Here's the source for
mattr_accessor
As you can see, they're pretty much identical.
As to why there are two different versions? Sometimes you want to write
cattr_accessor
in a module, so you can use it for configuration info like Avdi mentions.However,
cattr_accessor
doesn't work in a module, so they more or less copied the code over to work for modules also.Additionally, sometimes you might want to write a class method in a module, such that whenever any class includes the module, it gets that class method as well as all the instance methods.
mattr_accessor
also lets you do this.However, in the second scenario, it's behaviour is pretty strange. Observe the following code, particularly note the
@@mattr_in_module
bits