before_save :create_remember_token
private
def create_remember_token
self.remember_token = SecureRandom.urlsafe_base64
end
请问这里,self.remember_token 的 self 能否去掉?不加 self 好像运行不正常,但是不应该默认是 self 的么
不加 self 相当于是给一个临时变量 remember_token 赋值,加 self,相当于是调用 remember_token=(...) 这个方法。2 者完全不同的。
self 是当前的正在运行的代码的 context 上下文的引用,如果记得没错的话,这个跟 Ruby 方法的查询方式和优先级有关。
如果是一个 ActiveRecord 对象,那么在对象初始化的时候,会根据表字段,给每个字段生成一对 get / set 方法,比如remember_token
,remember_token=(value)
这两个方法。第二个 set 方法如果在另外一个方法内被调用的时候,在没有添加 self 的时候,会优先处理为你想要声明一个局部变量,而不是去尝试调用之前生成的remember_token=(value)
方法,如果显示声明了 self
后,则告诉 Ruby 解释器你这里不是要声明一个局部变量,而是一个 set 方法调用。
想要理解 Ruby 解释器为什么这样排列优先级的话,不如反过来思考,如果解释器的查询逻辑刚刚好相反的话,你要怎样才能明确的告诉解释器你这里要声明一个跟表字段同名的局部变量,而不是去调用 set 方法呢?
class Foo
def test=(value)
puts "test=#{value}"
end
def run
self.test = 1
test = 2
send :ptest=, 3
ptest = 4
end
private
def ptest=(value)
puts "ptest=#{value}"
end
end
Foo.new.run
# test=1
# ptest=3
@doitian private assignment method 是个例外 ,其它的没有问题,我忘了这个细节了
class Foo
def test=(value)
puts "test=#{value}"
end
def run
self.test = 1
test = 2
ptest 4
end
private
def ptest(value)
puts "ptest=#{value}"
end
end
Foo.new.run
test=1
ptest=4