美文网首页
ruby的self与访问器

ruby的self与访问器

作者: spike15 | 来源:发表于2016-06-08 11:52 被阅读0次

    在学习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与访问器

          本文链接:https://www.haomeiwen.com/subject/qrdjdttx.html