什么是Rails模块中的mattr_accessor?
我在Rails文档中找不到这个,但是在正常的Ruby 类中, 'mattr_accessor'是'attr_accessor' (getter&setter)的模块推论。
例如。 在一个class级
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
(Module 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
简称:
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
这两个版本都允许您访问模块级别的variables,如下所示:
>> Config.hostname = "example.com" >> Config.admin_email = "admin@example.com" >> Config.hostname # => "example.com" >> Config.admin_email # => "admin@example.com"
这是cattr_accessor
的源cattr_accessor
和
这是mattr_accessor
的源mattr_accessor
正如你所看到的,它们几乎完全相同。
至于为什么有两个不同的版本? 有时候你想在模块中写cattr_accessor
,所以你可以用它来configuration信息, 比如Avdi提到 。
但是, cattr_accessor
在模块中不起作用,所以它们或多或less地将代码复制到模块中。
此外,有时您可能想要在模块中编写一个类方法,例如,只要有任何类包含该模块,就会得到该类方法以及所有实例方法。 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"