Pergunta

Eu não poderia realmente encontrar este na documentação Rails, mas parece que 'mattr_accessor' é o módulo corolário para 'attr_accessor' ( getter e setter) em um normal de rubi class .

Por exemplo. em uma classe

class User
  attr_accessor :name

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

Por exemplo. em um módulo

module Authentication
  mattr_accessor :current_user

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

Este método auxiliar é fornecido pelo ActiveSupport .

Foi útil?

Solução

trilhos estende rubi com ambos mattr_accessor (Módulo de assessor) e cattr_accessor (bem como versões _reader / _writer). Como attr_accessor de Ruby gera métodos getter / setter para casos , cattr/mattr_accessor fornecer métodos getter / setter no class ou módulo nível. Assim:

module Config
  mattr_accessor :hostname
  mattr_accessor :admin_email
end

é a abreviação de:

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

Ambas as versões permitem que você acessar as variáveis ??de nível de módulo como assim:

>> Config.hostname = "example.com"
>> Config.admin_email = "admin@example.com"
>> Config.hostname # => "example.com"
>> Config.admin_email # => "admin@example.com"

Outras dicas

Eis a fonte para cattr_accessor

E

Eis a fonte para mattr_accessor

Como você pode ver, eles são praticamente idênticos.

Quanto ao porquê existem duas versões diferentes? Às vezes você quer escrever cattr_accessor em um módulo, para que você possa usá-lo para informações de configuração como Avdi menciona .
No entanto, cattr_accessor não trabalho em um módulo, para que eles mais ou menos copiou o código mais ao trabalho para os módulos também.

Além disso, às vezes você pode querer escrever um método de classe em um módulo, de modo que sempre que qualquer classe inclui o módulo, ele recebe esse método classe, bem como todos os métodos de instância. mattr_accessor também permite que você faça isso.

No entanto, no segundo cenário, de comportamento é muito estranho. Observe o seguinte código, particularmente notar os bits @@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"
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top