如何调用回调?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何调用回调?相关的知识,希望对你有一定的参考价值。
回调的环境是什么?
例如,在标准Ruby on Rails Tutorial“(http://rails-4-0.railstutorial.org/book/modeling_users)的6.20列表中,它具有:
class User < ActiveRecord::Base
before_save { self.email = email.downcase }
“电子邮件”来自哪里?我们是否在定义email
的函数中?或者实际上是@email
?
另外,我们在那里使用self.email
而不是@email
(或者只是email
,如果它与@email
相同)有一个重要的原因吗?或者只是风格或教学?
答案
这里有几件事情在一起:
- 在保存模型实例的上下文中调用该块,因此块中的
self
是保存的User
。块也传递参数,但您不必使用它。 - Ruby中的局部变量未显式声明,当您第一次尝试为它们赋值时,它们会被隐式声明。
- 方法调用的隐式接收器是
self
。 - 但局部变量优先于方法调用,因此mutator方法(如
self.email=
)需要一个显式接收器来区分它与局部变量。 - 实例变量(
@email
)与ActiveRecord模型中的属性无关。 - 访问者(
self.email
或只是email
,如果没有email
局部变量)和mutator方法(self.email=
)的ActiveRecord对象使用属性,而不是实例变量。
所以这:
before_save { self.email = email.downcase } # (1)
也可以写成:
before_save { |user| user.email = user.email.downcase } # (2)
甚至:
before_save { |user| user.send(:email=, user.send(:email).downcase) } # (3)
主要的功能差异是(2)要求email
和email=
方法公开。
另一答案
回调在对象(示例中的用户)范围内运行。 self.email=
是一个对象方法,而@email
是一个实例变量。
ActiveRecord自动为相应数据库表中的所有列创建方法(getter和setter)(我假设你在email
表中有users
列)。
请注意,使用@email =
而不是self.email =
将创建实例变量,并且不会更新数据库中的列。
以上是关于如何调用回调?的主要内容,如果未能解决你的问题,请参考以下文章
对“xxx”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们。 错误解决一例。(代码片段