为什么我可以在没有attr_writer的情况下设置哈希属性?

sak*_*ias 3 ruby attributes

如果我理解正确,红宝石允许设置,只有当他们被声明为可写的实例属性(例如,通过attr_writer,attr_accessor或定制的setter方法).我注意到我可以在没有显式编写器方法的情况下设置哈希属性:

class HashSetter
  attr_reader :hash

  def initialize
    @hash = {}
  end

  def set_hash
    self.hash[:message] = 'haha'
  end
end

obj = HashSetter.new
obj.set_hash
puts obj.hash
# -> {:message=>"haha"}
Run Code Online (Sandbox Code Playgroud)

正如所料,如果我有一个"常规"变量而不是哈希值,相同的代码将无法工作:

class VarSetter
  attr_reader :var

  def initialize
    @var = nil
  end

  def set_var
    self.var = 10
  end
end

obj = VarSetter.new
obj.set_var
# ->
# check_accessors.rb:26:in `set_var': undefined method `var=' for #<VarSetter:0x00000001cba510 @var=nil> (NoMethodError)
Run Code Online (Sandbox Code Playgroud)

为什么我可以:hash在第一段代码中设置属性?

tor*_*o2k 7

在您的第一个示例中,您没有设置hash属性,您实际上是获取属性(使用属性读取器)并[]=在其上调用方法.你没有被允许做的attr_writer是直接分配self.hash,即你不能写self.hash = {},这就是你在第二个例子中得到错误的原因.