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

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,308评论 19 139
  • 班上有个很有个性的同学 有次晚自习上到一半就潇洒的走了 甚至有时候不来 上课也有时请假 她很美 而且美的很有自己...
    林深时见鹿有阅读 1,514评论 0 0
  • 头发的线条还是掌控不太好,颜色也有点上深了~不过经过几天的练习收获还是很多的!相信再接下去的基础课上,我一定会收获...
    翾萱宝宝阅读 1,222评论 0 0
  • 这几天沸沸扬扬都在传阿里高管出轨的事,是同一个小区的邻居,孩子还跟我们家小朋友一个幼儿园,在各种群有交集,也在朋友...
    kimi妈妈阅读 1,579评论 0 0
  • 现在大家都在提知识变现,很多人开始挖掘自身优势,或是赶紧去学新的东西,为以后升值加薪/直播/网课/写作来做准备。不...
    马可吃菠萝阅读 7,845评论 0 14