我无法在Rails文档中找到这个,但似乎'mattr_accessor'是普通Ruby 类中'attr_accessor'(getter&setter)的模块推论.
例如.在课堂上
class User attr_accessor :name def set_fullname @name = "#{self.first_name} #{self.last_name}" end end
例如.在一个模块中
module Authentication mattr_accessor :current_user def login @current_user = session[:user_id] || nil end end
这个帮助方法由ActiveSupport提供.
Rails使用mattr_accessor
(模块访问器)和cattr_accessor
(以及_ reader
/ _writer
版本)扩展Ruby .作为Ruby的attr_accessor
生成用于getter/setter方法的实例,cattr/mattr_accessor
提供在吸气/ setter方法类或模块的水平.从而:
module Config mattr_accessor :hostname mattr_accessor :admin_email end
是短的:
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
这两个版本都允许您访问模块级变量,如下所示:
>> Config.hostname = "example.com" >> Config.admin_email = "admin@example.com" >> Config.hostname # => "example.com" >> Config.admin_email # => "admin@example.com"
这是源的 cattr_accessor
和
这是源的 mattr_accessor
如你所见,它们几乎完全相同.
至于为什么有两个不同的版本?有时您想要cattr_accessor
在模块中编写,因此您可以将其用于配置信息,如Avdi提及.
但是,cattr_accessor
在模块中不起作用,因此它们或多或少地复制了代码,以便为模块工作.
此外,有时您可能希望在模块中编写类方法,这样每当任何类包含模块时,它都会获得该类方法以及所有实例方法.mattr_accessor
也让你这样做.
但是,在第二种情况下,它的行为很奇怪.请注意以下代码,特别注意这些@@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"