ruby的self与访问器

在学习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
其实就是调用了上面的setter方法, self.remember_token = (User.new_token)
这里的方法调用, 看上去就和赋值一模一样了
而之后User.digest(remember_token)中的remember_token则是调用了getter方法

这里又牵涉到self的用法, 关于self:

  • self在class内, 其指的是class本身
  • self在def内, 则表示类的实例

所以在def内, 使用self.method调用一个实例方法。
ruby贯彻了DRY, 在大部分情况下, 我们都可以不使用self, 隐式调用一个实例方法,
但是, setter方法不在此列, 也就是说setter方法需要显式调用

而这里的

  • self.remember_token = User.new_token 是一个显式调用
  • User.digest(remember_token) 是一个隐式调用

其实这里是可以使用实例变量来替代的:

def remember
  @remember_token = User.new_token
  update_attribute(:remember_digest, User.digest(@remember_token))
end

至此, 让我也对实例变量和访问器有了更全面的了解

你可能感兴趣的:(ruby的self与访问器)