我应该如何理解ruby中的标识符?

时间:2012-10-12 04:58:02

标签: ruby variables syntax accessor

我正在完成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_usercurrent_user:current_user。我最熟悉C,C ++,PHP,Java,JavaScript。如果这些语言有类似的话,那将有助于我更好地理解正在发生的事情。

3 个答案:

答案 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。在这些方法之外,你总是使用方法调用。