Ruby-on-rails Rails 模块中的 mattr_accessor 是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/185573/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 20:43:23  来源:igfitidea点击:

What is mattr_accessor in a Rails module?

ruby-on-railsrubyclassmoduleactivesupport

提问by JasonOng

I couldn't really find this in Rails documentation but it seems like 'mattr_accessor'is the Modulecorollary for 'attr_accessor'(getter & setter) in a normal Ruby class.

我在 Rails 文档中真的找不到这个,但似乎“mattr_accessor”是普通 Ruby类中“attr_accessor”(getter & setter)的模块推论。

Eg. in a class

例如。在一个班级

class User
  attr_accessor :name

  def set_fullname
    @name = "#{self.first_name} #{self.last_name}"
  end
end

Eg. in a module

例如。在一个模块中

module Authentication
  mattr_accessor :current_user

  def login
    @current_user = session[:user_id] || nil
  end
end

This helper method is provided by ActiveSupport.

此辅助方法由ActiveSupport提供。

回答by Avdi

Rails extends Ruby with both mattr_accessor(Module accessor) and cattr_accessor(as well as _reader/_writerversions). As Ruby's attr_accessorgenerates getter/setter methods for instances, cattr/mattr_accessorprovide getter/setter methods at the classor modulelevel. Thus:

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

is short for:

简称:

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

Both versions allow you to access the module-level variables like so:

两个版本都允许您访问模块级变量,如下所示:

>> Config.hostname = "example.com"
>> Config.admin_email = "[email protected]"
>> Config.hostname # => "example.com"
>> Config.admin_email # => "[email protected]"

回答by Orion Edwards

Here's the source for cattr_accessor

这是来源 cattr_accessor

And

Here's the source for mattr_accessor

这是来源 mattr_accessor

As you can see, they're pretty much identical.

如您所见,它们几乎相同。

As to why there are two different versions? Sometimes you want to write cattr_accessorin a module, so you can use it for configuration info like Avdi mentions.
However, cattr_accessordoesn't work in a module, so they more or less copied the code over to work for modules also.

至于为什么会有两个不同的版本?有时你想cattr_accessor在一个模块中编写,所以你可以将它用于配置信息,如 Avdi 提到的
但是,cattr_accessor在模块中不起作用,因此他们或多或少地复制了代码以也适用于模块。

Additionally, sometimes you might want to write a class method in a module, such that whenever any class includes the module, it gets that class method as well as all the instance methods. mattr_accessoralso lets you do this.

此外,有时您可能希望在模块中编写类方法,这样无论何时任何类包含该模块,它都会获取该类方法以及所有实例方法。mattr_accessor也可以让你这样做。

However, in the second scenario, it's behaviour is pretty strange. Observe the following code, particularly note the @@mattr_in_modulebits

然而,在第二种情况下,它的行为很奇怪。观察以下代码,特别注意@@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"