Rails教程:实例变量的使用
Rails Tutorial: use of instance variables
我在 Rails 教程的第 8.4.3 - Forgetting Users 部分。
# app/helpers/session_helper.rb
module SessionsHelper
...
# Returns the user corresponding to the remember token cookie.
def current_user
if (user_id = session[:user_id])
@current_user ||= User.find_by(id: user_id)
elsif (user_id = cookies.signed[:user_id])
user = User.find_by(id: user_id)
if user && user.authenticated?(cookies[:remember_token])
log_in user
@current_user = user
end
end
end
# Logs out the current user
def log_out
forget(current_user)
session.delete(:user_id)
@current_user = nil
end
...
end
在 current_user
方法中,我们将用户分配给 @current_user
实例变量。我不明白为什么我们不在 log_out
方法中使用相同的实例变量(在该方法中 current_user
没有前缀 @ 符号)。 current_user
是从哪里来的,因为它没有作为参数传递给该方法?
Ruby 在方法调用和局部变量之间没有区别。这就是为什么 current_user
可能看起来两者都一样的原因。
在您的情况下,它是定义的方法。
您实际上可以同时使用 @current_user
和 current_user
,因为该方法的返回值应等于 @current_user
.
current_user
是在您发布的页面片段中定义的方法。
@current_user
是 BY current_user
设置的实例变量
所以当你看代码时:
# Defines a method called log_out
def log_out
# Calls the 'forget' method on the result of the 'current_user' method,
# which sets @current_user
forget(current_user)
# Deletes the session variable named 'user_id'
session.delete(:user_id)
# Resets @current_user to nil, because there should no longer be one
@current_user = nil
end
如果我想换个角度看,我可以说:
def log_out
# Sets @current_user
current_user
# Calls the forget method on the variable @current_user
forget(@current_user)
session.delete(:user_id)
@current_user = nil
end
但是我无法将最后一行更改为 current_user = nil
而不是 @current_user = nil
,因为这样我就将 nil 值分配给方法的名称而不是实例变量。
方法调用和变量在 Ruby 中看起来如此相似的部分原因是一切都作为对象处理,因此方法 本质上 只是一个变量,其值是一段代码(与我们所说的 "block" 和方法存在技术差异,但从概念上讲这是一个不错的类比)。当我们定义一个方法时,我们将它保存到一个或多或少的变量中。因此,如果我们考虑方法 "current_user",我们可能会将其视为一个变量 "current_user",其值为 forget(current_user); session.delete(:user_id); @current_user=nil
.
当然,这是过于简单化了,但是在您继续学习时值得牢记这一点。
我在 Rails 教程的第 8.4.3 - Forgetting Users 部分。
# app/helpers/session_helper.rb
module SessionsHelper
...
# Returns the user corresponding to the remember token cookie.
def current_user
if (user_id = session[:user_id])
@current_user ||= User.find_by(id: user_id)
elsif (user_id = cookies.signed[:user_id])
user = User.find_by(id: user_id)
if user && user.authenticated?(cookies[:remember_token])
log_in user
@current_user = user
end
end
end
# Logs out the current user
def log_out
forget(current_user)
session.delete(:user_id)
@current_user = nil
end
...
end
在 current_user
方法中,我们将用户分配给 @current_user
实例变量。我不明白为什么我们不在 log_out
方法中使用相同的实例变量(在该方法中 current_user
没有前缀 @ 符号)。 current_user
是从哪里来的,因为它没有作为参数传递给该方法?
Ruby 在方法调用和局部变量之间没有区别。这就是为什么 current_user
可能看起来两者都一样的原因。
在您的情况下,它是定义的方法。
您实际上可以同时使用 @current_user
和 current_user
,因为该方法的返回值应等于 @current_user
.
current_user
是在您发布的页面片段中定义的方法。
@current_user
是 BY current_user
所以当你看代码时:
# Defines a method called log_out
def log_out
# Calls the 'forget' method on the result of the 'current_user' method,
# which sets @current_user
forget(current_user)
# Deletes the session variable named 'user_id'
session.delete(:user_id)
# Resets @current_user to nil, because there should no longer be one
@current_user = nil
end
如果我想换个角度看,我可以说:
def log_out
# Sets @current_user
current_user
# Calls the forget method on the variable @current_user
forget(@current_user)
session.delete(:user_id)
@current_user = nil
end
但是我无法将最后一行更改为 current_user = nil
而不是 @current_user = nil
,因为这样我就将 nil 值分配给方法的名称而不是实例变量。
方法调用和变量在 Ruby 中看起来如此相似的部分原因是一切都作为对象处理,因此方法 本质上 只是一个变量,其值是一段代码(与我们所说的 "block" 和方法存在技术差异,但从概念上讲这是一个不错的类比)。当我们定义一个方法时,我们将它保存到一个或多或少的变量中。因此,如果我们考虑方法 "current_user",我们可能会将其视为一个变量 "current_user",其值为 forget(current_user); session.delete(:user_id); @current_user=nil
.
当然,这是过于简单化了,但是在您继续学习时值得牢记这一点。