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.
我在Rails文档中找不到这个,但似乎“mattr_accessor”是普通Ruby类中“attr_accessor”(getter & setter)的模块推论。
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.
这个助手方法由ActiveSupport提供。
2 个解决方案
#1
162
Rails extends Ruby with both mattr_accessor
(Module accessor) and cattr_accessor
(as well as _reader
/_writer
versions). As Ruby's attr_accessor
generates getter/setter methods for instances, cattr/mattr_accessor
provide getter/setter methods at the class or module level. Thus:
Rails通过mattr_accessor(模块访问器)和cattr_accessor(以及_reader/_writer版本)扩展了Ruby。当Ruby的attr_accessor为实例生成getter/setter方法时,cattr/mattr_accessor在类或模块级别提供getter/setter方法。因此:
module Config
mattr_accessor :hostname
mattr_accessor :admin_email
end
is short for:
的缩写:
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
Both versions allow you to access the module-level variables like so:
两个版本都允许您访问模块级的变量:
>> Config.hostname = "example.com"
>> Config.admin_email = "admin@example.com"
>> Config.hostname # => "example.com"
>> Config.admin_email # => "admin@example.com"
#2
36
Here's the source for cattr_accessor
这里是cattr_accessor的源代码。
And
和
Here's the source for mattr_accessor
这是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.
为什么有两个不同的版本?有时您想在模块中编写cattr_accessor,因此可以将它用于Avdi提到的配置信息。但是,cattr_accessor不能在模块中工作,因此它们或多或少地将代码复制到模块中。
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.
此外,有时您可能想要在模块中编写类方法,例如,每当任何类包含该模块时,它都会获得该类方法以及所有实例方法。mattr_accessor也允许您这样做。
However, in the second scenario, it's behaviour is pretty strange. Observe the following code, particularly note the @@mattr_in_module
bits
然而,在第二个场景中,它的行为非常奇怪。观察下面的代码,特别注意@@mattr_in_module位。
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"
#1
162
Rails extends Ruby with both mattr_accessor
(Module accessor) and cattr_accessor
(as well as _reader
/_writer
versions). As Ruby's attr_accessor
generates getter/setter methods for instances, cattr/mattr_accessor
provide getter/setter methods at the class or module level. Thus:
Rails通过mattr_accessor(模块访问器)和cattr_accessor(以及_reader/_writer版本)扩展了Ruby。当Ruby的attr_accessor为实例生成getter/setter方法时,cattr/mattr_accessor在类或模块级别提供getter/setter方法。因此:
module Config
mattr_accessor :hostname
mattr_accessor :admin_email
end
is short for:
的缩写:
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
Both versions allow you to access the module-level variables like so:
两个版本都允许您访问模块级的变量:
>> Config.hostname = "example.com"
>> Config.admin_email = "admin@example.com"
>> Config.hostname # => "example.com"
>> Config.admin_email # => "admin@example.com"
#2
36
Here's the source for cattr_accessor
这里是cattr_accessor的源代码。
And
和
Here's the source for mattr_accessor
这是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.
为什么有两个不同的版本?有时您想在模块中编写cattr_accessor,因此可以将它用于Avdi提到的配置信息。但是,cattr_accessor不能在模块中工作,因此它们或多或少地将代码复制到模块中。
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.
此外,有时您可能想要在模块中编写类方法,例如,每当任何类包含该模块时,它都会获得该类方法以及所有实例方法。mattr_accessor也允许您这样做。
However, in the second scenario, it's behaviour is pretty strange. Observe the following code, particularly note the @@mattr_in_module
bits
然而,在第二个场景中,它的行为非常奇怪。观察下面的代码,特别注意@@mattr_in_module位。
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"