Ruby 添加self关键字有什么区别?

Ruby 添加self关键字有什么区别?,ruby,self,Ruby,Self,当我开始学习Ruby时,我开始学习Michael Hartl的优秀作品。我刚刚重温了教程,并注意到示例应用程序代码的部分已经修改。在认证章节中,更改了两种方法: # SessionsHelper def sign_in(user) ... self.current_user = user end def sign_out self.current_user = nil ... end 以前,省略了关键字self。但是这个应用程序成功了。那么,如果它没有坏,为什么要修理它?se

当我开始学习Ruby时,我开始学习Michael Hartl的优秀作品。我刚刚重温了教程,并注意到示例应用程序代码的部分已经修改。在认证章节中,更改了两种方法:

# SessionsHelper
def sign_in(user)
  ...
  self.current_user = user
end

def sign_out
  self.current_user = nil
  ...
end
以前,省略了关键字
self
。但是这个应用程序成功了。那么,如果它没有坏,为什么要修理它?
self
增加了什么值?为什么使用它


我理解
self
定义类方法而不是实例方法。在模型中,使用
self
允许我们直接引用对象的属性。但我不能把这些点连起来,看看它是如何在助手中使用的。我以前在控制器中见过它,我不明白为什么我们要在那里使用它。

[Edit]

很可能教程的原始部分完全错了。省略“self”接收器会导致方法向方法局部变量“current_user”赋值,而不会产生其他影响

我下面的原始答案不正确,应该忽略(因为writer方法
foo=(x)
不能在没有接收者的情况下调用,其他方法也一样)

[下面的原始答案不正确]

使用“自我”接收器的原因可能是为了清楚

如果省略了“self”,那么在未经培训的人看来,您只是简单地将“user”变量分配给名为“current_user”的新变量,而没有其他效果。经验丰富的Ruby专家知道,如果对象实例上有一个名为“current_user”的方法,那么它将被调用,而不仅仅是创建和分配一个新变量,但是这个细节很容易被忽略,特别是如果该方法是继承的,或者没有在当前类定义部分声明


通过显式地使用“self”关键字,您清楚地表明您正在调用此对象实例上的方法。

[Edit]

很可能教程的原始部分完全错了。省略“self”接收器会导致方法向方法局部变量“current_user”赋值,而不会产生其他影响

我下面的原始答案不正确,应该忽略(因为writer方法
foo=(x)
不能在没有接收者的情况下调用,其他方法也一样)

[下面的原始答案不正确]

使用“自我”接收器的原因可能是为了清楚

如果省略了“self”,那么在未经培训的人看来,您只是简单地将“user”变量分配给名为“current_user”的新变量,而没有其他效果。经验丰富的Ruby专家知道,如果对象实例上有一个名为“current_user”的方法,那么它将被调用,而不仅仅是创建和分配一个新变量,但是这个细节很容易被忽略,特别是如果该方法是继承的,或者没有在当前类定义部分声明


通过显式地使用“self”关键字,您清楚地表明您正在对此对象实例调用一个方法。

如果在没有
self
关键字的情况下这样做有效,那么他们必须使用实例变量(b/c这会调用setter方法,但如果没有self,则会设置一个局部变量)。这些都不是一回事,在我看来,使用设置方法比使用实例变量要好得多(b/c直接设置ivar意味着您知道它的实现,但调用setter只包含一个方法的知识)。@Joshuacheck:不一定,可能有一个
attr\u访问器:current\u user
或一个显式方法
def current\u user=(new\u user)
,同样的语法也有效。确实有一个方法(在新旧版本中):
def current\u user=(user)@current\u user=user end
@joshuacheck根据我的经验,即使
current\u user=
是在没有
self
的情况下定义的,Ruby将创建局部变量而不是使用任何方法。@maerics否,它将设置局部变量而不是调用setter@VictorMoroz不确定你的意思,如果你说
self.current\u user=whatever
,那么你调用的是setter,如果你说
current\u user=whatever
,那么你设置的是一个本地变量,所以它以前一定是
@current\u user=whatever
。如果这在没有
self
关键字的情况下起作用,然后他们必须使用实例变量(b/c这会调用setter方法,但如果没有self,它会设置一个局部变量)。这些都不是一回事,在我看来,使用设置方法比使用实例变量要好得多(b/c直接设置ivar意味着您知道它的实现,但调用setter只包含一个方法的知识)。@Joshuacheck:不一定,可能有一个
attr\u访问器:current\u user
或一个显式方法
def current\u user=(new\u user)
,同样的语法也有效。确实有一个方法(在新旧版本中):
def current\u user=(user)@current\u user=user end
@joshuacheck根据我的经验,即使
current\u user=
是在没有
self
的情况下定义的,Ruby将创建局部变量而不是使用任何方法。@maerics否,它将设置局部变量而不是调用setter@VictorMoroz不确定你的意思,如果你说
self.current\u user=whatever
,那么你是在调用setter,如果你说
current\u user=whatever
,那么你是在设置一个本地变量,所以它以前一定是
@current\u user=whatever
。真的吗?如果
current\u user
在赋值的左侧部分没有使用
self
,Ruby将创建局部变量,而不是调用
current\u user
方法(即使定义了
current\u user=
)。这是我在这里遗漏的东西吗?-1。这完全是错误的<代码>foo=ba
class User
  attr_accessor :current_user

  def sign_in_1
    # Assigning local variable here
    current_user = "Foo"
  end

  def sign_in_2
    # Calling accessor method
    self.current_user = "Bar"
  end
end

u = User.new
u.sign_in_1
p u.current_user #=> nil
u.sign_in_2
p u.current_user #=> "Bar"