Ruby on rails Rails模块中的mattr_访问器是什么?

Ruby on rails Rails模块中的mattr_访问器是什么?,ruby-on-rails,ruby,class,module,activesupport,Ruby On Rails,Ruby,Class,Module,Activesupport,我在Rails文档中找不到这一点,但似乎'mattr\u accessor'是普通Ruby类中'attr\u accessor'(getter&setter)的模块的必然结果 在课堂上 class User attr_accessor :name def set_fullname @name = "#{self.first_name} #{self.last_name}" end end 在模块中 module Authentication mattr_accesso

我在Rails文档中找不到这一点,但似乎'mattr\u accessor'是普通Ruby类中'attr\u 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\u访问器(模块访问器)和
cattr\u访问器(以及
/
版本)扩展Ruby提供的。由于Ruby的
attr\u访问器
为实例生成getter/setter方法,
cattr/mattr\u访问器
在类或模块级别提供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\u访问器
,以便将其用于配置信息。
但是,
cattr\u访问器
在模块中不起作用,因此他们或多或少地将代码复制到模块中

此外,有时您可能希望在模块中编写一个类方法,这样每当任何类包含该模块时,它都会获得该类方法以及所有实例方法
mattr_访问器也允许您执行此操作

然而,在第二个场景中,它的行为非常奇怪。遵守以下代码,特别注意模块中的
@@mattr\u

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"

当直接设置默认url选项(mattr_访问器)时,这是一个让我很难理解的问题。Once类将以一种方式设置它们,而另一种方式将以另一种方式设置它们,从而创建无效链接。在Rails的最新版本中,
cattr.*
现在是
mattr.*
的别名。请参见示例中的,您解释了
mattr\u访问器
是类实例变量(
@variable
s)的缩写,但源代码似乎表明它们实际上是在设置/读取类变量。你能解释一下这种区别吗?