如何使用Ruby的self关键字

问题描述 投票:63回答:4

据我对self的了解,它指的是该类的当前实例。

这不是始终都是默认行为吗?例如,不是

self.var_one = method(args)

相当于

var_one = method(args) 

如果是,self的用途是什么?

ruby instance self
4个回答
57
投票

在大多数情况下,self.foo确实是多余的,因为您可以只写foo以达到相同的效果,但是在这种情况下则不是,并且需要self

[var_one = method(args)将创建一个名为var_one的局部变量,它将不会调用任何方法或对self进行任何其他操作。

[self.var_one = method(args)将使用参数var_one=调用self上的方法method(args)

另一种不可选使用self的情况是,如果您想将其作为方法的参数,即some_method(self)传递,没有self关键字就无法这样做。


118
投票

有几个重要的用途,其中大部分基本上是用于区分实例方法,类方法和变量。

首先,这是定义类方法的最佳方法:

class Foo
  def self.bar
    "class method bar"
  end

  def bar
    "instance method bar"
  end
end

Foo.bar  #returns "class method bar"

foo = Foo.new
foo.bar #returns "instance method bar"

此外,在实例方法中,self引用实例,在类方法中,它引用类,并且始终可以用来与局部变量区分开。

class Bar
  def self.foo
    "foo!"
  end

  def baz
    "baz!"
  end

  def self.success
    foo #looks for variable foo, doesn't find one, looks for class method foo, finds it, returns "foo!"
  end

  def self.fail
    baz #looks for variable baz, doesn't find one, looks for class method baz, doesn't find one, raises exception
  end

  def instance_success
    baz #looks for variable baz, doesn't find one, looks for instance method baz, finds it, returns "baz!"
  end

  def instance_fail
    foo #looks for variable foo, doesn't find one, looks for instance method foo, doesn't find one, raises exception
  end

  def local_variable
    baz = "is my favorite method"
    baz #looks for variable baz, finds it, returns "is my favorite method"
  end

  def disambiguate
    baz = " is my favorite method"
    self.baz + baz #looks for instance method baz, finds it, looks for local variable baz, finds it, returns "baz! is my favorite method"
  end
end

因此,最后,在许多情况下都可以避免使用self,但是使用它来确保以后再也不会无意间产生命名冲突通常是有帮助的。有时,这些错误可能会导致很难发现的错误。最后,这通常是个人风格的问题。


如评论中所述,还有一件非常重要的事情:

在类中,如果您有这样的方法:

def bar=(string)
  ...
end

然后用另一种方法调用:

def other_method
  bar = "abcd"
end

不会调用您的bar=方法,它将创建一个局部变量bar。因此,在这种情况下,您可以使用self告诉Ruby不要创建本地变量:

def other_method
  self.bar = "abcd"
end

如果要使用方法名称作为参数,则同样适用:

def example
  ...
end

def other_thing(example)
  self.example(example)
end

如果您不使用self,Ruby将假定您的意思是具有相同名称的局部变量。

因此,通常,方法名称中的self用于区分类变量和实例变量,当Ruby需要帮助区分方法调用和局部变量或局部变量赋值时,在其他地方都可以使用它。

我希望这是有道理的。


4
投票

self的另一种用法是声明类方法(类似于Java中的静态方法。)>

class foo
 def self.bar
  #do class related stuff here
 end
end

话虽这么说,您也可以使用def foo.bar代替方法签名。


4
投票

这里是一个例子:

© www.soinside.com 2019 - 2024. All rights reserved.