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



如果我理解正确的话,Ruby 允许仅在实例属性被声明为可写时设置实例属性(例如,通过 attr_writerattr_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"}

正如预期的那样,如果我有一个"常规"变量而不是哈希,同样的代码将不起作用:

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)

为什么允许在第一段代码中设置 :hash 属性?

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

如果我理解正确,Ruby 允许仅在实例属性声明为可写时才设置实例属性

你误会了。 attr_writer :foo只是语法糖:

def foo=(value)
  @foo = value
end

然后,它允许您调用 object.foo = :bar ,这将调用以 :bar 作为参数的 foo= 方法。

无论声明如何,您始终可以分配实例变量attr_writer

相关内容

最新更新