我在Rails文档中找不到这一点,但似乎'mattr_accessor'是'attr_accessor' (getter & setter)在普通类中的Ruby模块推论。
例如:在一个班级里
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.提供
发布于 2008-10-09 01:49:22
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
简写为:
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"
发布于 2008-10-09 19:51:36
Here's the source for cattr_accessor
和
Here's the source for mattr_accessor
如您所见,它们几乎完全相同。
为什么会有两个不同的版本?有时你想在一个模块中编写cattr_accessor
,这样你就可以在配置信息like Avdi mentions中使用它。
然而,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"
https://stackoverflow.com/questions/185573
复制相似问题