在學(xué)習(xí)rails的過程中, 遇到了下面這樣一段代碼,里面的self.remember_token
讓我有些找不到方向碗旅。
class User < ActiveRecord::Base
attr_accessor :remember_token
def remember
self.remember_token = User.new_token
update_attribute(:remember_digest, User.digest(remember_token))
end
def User.new_token
SecureRandom.urlsafe_base64
end
end
乍看之下蒸健, self.remember_token
是一個變量,還用了等號賦值。
但其實這里的是一個實例方法僚纷。
在class里定義了attr_accessor :remember_token
, 而attr_accessor :remember_token
等價于:
def remember_token
@remember_token
end
def remember_token=(value)
@remember_token = value
end
第一個是讀方法(getter), 第二個是寫方法(setter)
注意第二個方法remember_token=
, 這里有一個=
再來看一下那行奇怪的代碼, self.remember_token = User.new_token
其實就是調(diào)用了上面的setter方法, self.remember_token = (User.new_token)
這里的方法調(diào)用, 看上去就和賦值一模一樣了
而之后User.digest(remember_token)
中的remember_token
則是調(diào)用了getter方法
這里又牽涉到self
的用法, 關(guān)于self
:
- self在class內(nèi), 其指的是class本身
- self在def內(nèi), 則表示類的實例
所以在def內(nèi), 使用self.method
調(diào)用一個實例方法伪煤。
ruby貫徹了DRY, 在大部分情況下, 我們都可以不使用self
, 隱式調(diào)用一個實例方法,
但是, setter方法不在此列, 也就是說setter方法需要顯式調(diào)用
而這里的
-
self.remember_token = User.new_token
是一個顯式調(diào)用 -
User.digest(remember_token)
是一個隱式調(diào)用
其實這里是可以使用實例變量來替代的:
def remember
@remember_token = User.new_token
update_attribute(:remember_digest, User.digest(@remember_token))
end
至此, 讓我也對實例變量和訪問器有了更全面的了解