如何在内存中管理虚拟属性?

时间:2017-09-09 14:37:13

标签: ruby-on-rails ruby memory-management computed-properties virtual-attribute

我正在浏览迈克尔·哈特尔的rails tutorial,他已经定义了一个虚拟属性remember_token,然后在remember实例方法中为其指定了一个值:

class User < ApplicationRecord
  attr_accessor :remember_token
  ...

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

然后,在调用remember后,他在辅助方法中访问虚拟属性的值:

def remember(user)
  user.remember
  cookies.permanent.signed[:user_id] = user.id
  cookies.permanent[:remember_token] = user.remember_token
end

我的解释是,在执行remember方法之后(以及remember_token被分配的位置,它已从内存中删除。显然这不是这种情况,因为在分配新内容时它仍然可用价值为cookies.permanent[:remember_token]

我想我的混乱源于数据持久性。假设在remember_token的帮助下将attr_accessor变为实例变量,它何时正式变为不可用?

1 个答案:

答案 0 :(得分:0)

你的假设是错误的。

“虚拟属性”实际上只是一个术语,用于模型中的普通旧实例属性,以区别于持久存储的数据库支持的属性。

实例属性保留其值,只要封装它们的对象存在(或者您明确地将值设置为n)。该对象一直存在,直到垃圾收集器can determine that it is no longer referenced

class Person
  attr_accessor :name

  def initialize(name: nil)
    @name = name
    # or using the accessor
    self.name = name
  end
end

因此,如果我们创建Person的实例,它当然会保留name的值:

jane = Person.new(name: 'Jane')
jane.name # => 'Jane'

您可能会感到困惑的是局部变量,它们仅在定义它们的块中可用:

class Person
  attr_accessor :name

  def say_hello
    # this local variable is garbage collect after the method is called
    phrase =  "Hello, my name is "
    puts phrase + name # we can omit self since it is implied
  end
end