我正在完成Michael Hartl的RoR教程。这里是SessionsHelper的一些代码:
module SessionsHelper
def sign_in(user)
cookies.permanent[:remember_token] = user.remember_token
self.current_user = user
end
def current_user=(user)
@current_user = user
end
def current_user
@current_user ||= User.find_by_remember_token(cookies[:remember_token])
end
def current_user?(user)
user == current_user
end
def signed_in?
!current_user.nil?
end
def sign_out
self.current_user = nil
cookies.delete(:remember_token)
end
end
我从这段代码中无法理解许多事情。
current_user?
中,current_user
是变量还是调用方法current_user
?我不明白在这种情况下如何确定current_user
的价值。
current_user
中,@current_user
是一个实例变量。什么是实例变量(即什么类?)?如果您查看sign_in(user)
方法,可以看到为self.current_user
分配了对象user
的值。但是(假设self属于UsersController类,因为UsersController < ApplicationController
并且在ApplicationController
的定义中有一行包含SessionsHelper
),没有实例变量current_user
的定义对于self
对象。
current_user=
我们如何使用@current_user
,但在current_user?
我们只使用current_user
?我已经完成了对StackOverflow的先决条件搜索,但还没有找到所有这些差异的良好解释。我尝试学习的很大一部分是何时使用@current_user
,current_user
,:current_user
。我最熟悉C,C ++,PHP,Java,JavaScript。如果这些语言有类似的话,那将有助于我更好地理解正在发生的事情。
答案 0 :(得分:2)
在current_user?方法中,current_user是一个变量,还是一个变量 调用方法current_user?
这是方法,因为范围内没有该名称的词汇。
在方法current_user中,@ current_user是一个实例变量。 什么是实例变量(即什么类?)?
它是具有混合模块SessionsHelper
(通常带有include SessionsHelper
)的任何类的实例的实例变量。
此模块中定义了如果查看sign_in(user)方法,可以看到self.current_user被赋值为对象的值 用户。但是(假设self属于UsersController类,因为 UsersController&lt; ApplicationController和在定义中 ApplicationController有一行包含SessionsHelper) 没有为实例变量current_user定义 自我对象。
sign_in
以及setter方法current_user=
。 self.current_user = user
会将带有参数:current_user=
的消息user
发送给self
。由于sign_in来自这个模块,因此很可能该消息调度将转到此模块中定义的setter,尽管可能由包含此模块的类或模块定义同名的setter。包含在此模块之后,在这种情况下,将首先在调度搜索中找到这些方法。
current_user =我们如何使用@current_user但是在 当前用户?我们只使用current_user?
在定义时,限制直接实例变量访问setter和getter方法(有时是初始化)被认为是一种好习惯。在这种情况下,通过重用current_user
谓词中的current_user?
getter,我们可以保留getter中@current_user ||= User.find_by...
表达式的缓存或获取行为。
答案 1 :(得分:2)
只是为了补充其他答案:
在方法
current_user
中,@current_user
是一个实例变量。什么是的实例变量(即什么类?)?
实例变量不属于类。它们属于实例,这就是它们被称为实例变量的原因。它们总是属于self
,即消息的接收者所在的任何对象。
实例变量神奇地存在,第一次分配时,它们不会在任何地方声明。
答案 2 :(得分:1)
这是面向对象编程中的一个基本概念,称为encapsulation。您有一个变量@current_user
,但不直接使用该变量。您可以通过名为getters和setter的方法使用它。 getters用于获取变量en setters的值以设置变量的值。
在这种情况下,getter方法为current_user
,setter方法为current_user=
。只有在getter和setter中,才能直接使用变量@current_user
。在这些方法之外,你总是使用方法调用。