【问题标题】:How are virtual attributes managed in memory?虚拟属性如何在内存中管理?
【发布时间】:2018-02-18 06:46:49
【问题描述】:

我正在查看 Michael Hartl 的 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 的位置,它会从内存中删除。显然这里不是这种情况,因为在为 @987654329 分配新值时仍然可以使用它@。

我想我的困惑源于数据持久性。假设remember_tokenattr_accessor的帮助下变成了一个实例变量,那么它什么时候正式变得不可用?

【问题讨论】:

  • 当对象消失时。实例方法永远不会“变得不可用”,它们是定义它们的对象的一部分。
  • 对不起。可能不是 实例方法 本身,而是实例方法产生的值。
  • 这些值像任何其他值一样被垃圾收集。只要有对它们的引用,它们就不会被删除。

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


【解决方案1】:

你的假设是错误的。

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

只要封装它们的对象存在(或者您明确地将值设为 nil),实例属性就会保留它们的值。该对象存在直到垃圾收集器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

【讨论】:

  • “假设remember_token在attr_accessor的帮助下变成了一个实例变量”也是错误的——attr_accessor通过元编程创建了setter和getter方法。它不声明实例变量。实例变量在被赋值时被创建。
  • 感谢您的详细回答。不过我必须问一下,您的意思是在解释中使用name 而不是bar
  • 糟糕,我是说名字。
猜你喜欢
  • 2023-03-15
  • 1970-01-01
  • 2011-07-24
  • 2021-11-07
  • 1970-01-01
  • 1970-01-01
  • 2012-01-10
  • 2014-07-14
  • 1970-01-01
相关资源
最近更新 更多