比如有一个 class
class Log
  include Mongoid::Document
  include Mongoid::Timestamps::Created
  field :task_ids, type: Array ,:default => []
  protected
  before_save :save_task_ids
  def save_task_ids
      task_ids = somevalue
  end
end
我测试下来 task_ids= 这句话被理解为给一个局部变量赋值了,如果是要给 field 赋值,必须是用 self.task_ids= 请问在 ruby 里如果隐含调用 self 的实例方法,是否局部变量赋值优先于 self 的 setter 方法?
局部变量不存在的时候不会。 从你例子的情况看,是因为 db 属性字段都是通过 method missing 实现的,其实 task_ids=这个方法还没定义。
赋值方法一定要显示调用 self。ruby 看到赋值语句就会建立一个局部变量,即使没有实际运行
class A
  def name=(name)
    @name = name
  end
  def name
    "Class A"
  end
  def test_setter
    name = "A" 
    p name #=> "A"
    p @name #=> nil
  end
  def test_scope
    p name #=> "Class A"
    name = "A"  if false
    p name #=> nil
  end
end
#9 楼 @night_song 我觉得 define_method 似乎和直接定义 method 没区别阿.. 确定是 local variable 优先吗?
class A
  attr_accessor :name
  def initialize name
    @name = name
  end
  def change_name
    change_me
  end
  private
  def change_me
    puts %(
           puts name #=> #{name}\n
           puts self.name #=> #{self.name}\n
           puts name=bar;self.name #=> #{name='bar';self.name}\n
           puts name #=> #{name}
           puts self.methods.eql?(methods) #=> #{self.methods.eql?(methods)}\n
           puts send(:name=,'bar');self.name #=> #{send(:name=,'bar');self.name}
           )
  end
end
a = A.new "foo"
a.change_name
输出结果
puts name #=> foo
puts self.name #=> foo
puts name=bar;self.name #=> foo
puts name #=> bar
puts self.methods.eql?(methods) #=> true
puts send(:name=,'bar');self.name #=> bar
可见 self 也被 'private'了
其实 task_id 读写是在 field :task_ids, type: Array ,:default => [] 定义的,这里没必要用 method_missing ...
其实规则很简单 ... a = x 总是赋值语句而不是方法调用 a.b = x 总是方法调用
即使 setter 是 public method,也必须明确前缀 self,这是 ruby 中一个特例。 另外 setter 是 private 或 protected method 的话,很特殊,必须加 self。 the well-grounded rubyist p123. 有详细的介绍。 #14 楼 @aNdReW_Qx
