什么是Rails模块中的mattr_accessor?
-
06-07-2019 - |
题
我无法在Rails文档中找到这一点,但似乎'mattr_accessor'是'attr_accessor'的模块的必然结果( getter& setter)在普通的Ruby 类。
EG。在课堂上
class User
attr_accessor :name
def set_fullname
@name = "#{self.first_name} #{self.last_name}"
end
end
EG。在模块中
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的 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
两个版本都允许您访问模块级变量,如下所示:
>> Config.hostname = "example.com"
>> Config.admin_email = "admin@example.com"
>> Config.hostname # => "example.com"
>> Config.admin_email # => "admin@example.com"
其他提示
的来源
并且
的来源如您所见,它们几乎完全相同。
至于为什么有两个不同的版本?有时您想在模块中编写 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"
不隶属于 StackOverflow