Utilisation du mot clé ruby self?

D'après ce que je comprends du mot-clé self, Il se réfère simplement à l'instance actuelle de la classe. N'est-ce pas le comportement par défaut à tout moment de toute façon? Par exemple, n'est-ce pas

self.var_one = method(args) équivalent à juste var_one = method(args) ?

Si oui, quelle est l'utilisation de soi?

57
demandé sur hagello 2011-07-12 22:56:24

4 réponses

Dans la plupart des cas, self.foo est en effet redondant car vous pouvez simplement écrire foo pour le même effet, mais dans ce cas ce n'est pas le cas et le self est requis.

var_one = method(args) va créer une variable locale appelée var_one, elle n'appellera aucune méthode ou ne fera rien d'autre à self.

self.var_one = method(args) qui fera appel à la méthode var_one= sur self avec l'argument method(args).

Un Autre cas où l'utilisation de self est non facultatif, si vous souhaitez passer en argument à une méthode, c'est à dire some_method(self) - vous impossible de le faire sans le mot clé self.

51
répondu sepp2k 2011-07-12 18:59:44

Il existe plusieurs utilisations importantes, dont la plupart consistent essentiellement à désambiguïser entre les méthodes d'instance, les méthodes de classe et les variables.

Tout d'abord, c'est la meilleure façon de définir des méthodes de classe. C'est à dire:

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"

En outre, dans les méthodes d'instance self se réfère à l'instance, dans les méthodes de classe, il se réfère à la classe, et il peut toujours être utilisé pour distinguer des variables locales.

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

Donc, à la fin, vous pouvez éviter d'utiliser self dans de nombreux cas, mais il est souvent utile d'y aller avant et utilisez-le pour vous assurer que vous ne créez pas par inadvertance des conflits de nommage plus tard. Parfois, ceux-ci peuvent créer des bugs qui sont très difficiles à trouver. En fin de compte, c'est souvent une question de style personnel.


Mise à jour: comme indiqué dans les commentaires, une chose plus vraiment importante:

Dans une classe, si vous avez une méthode comme ceci:

def bar=(string)
  ...
end

Et dans une autre méthode, vous appelez:

def other_method
  bar = "abcd"
end

Il ne va pas appeler votre méthode bar=, il va créer une barre de variable locale. Si, dans ce cas, vous utilisez self pour dire à ruby de ne pas créer de variable locale, comme ceci:

def other_method
  self.bar = "abcd"
end

, La même chose s'applique si vous voulez prendre un argument avec le nom d'une méthode, comme ceci:

def example
  ...
end

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

Si vous avez laissé self, il supposerait que vous vouliez dire la variable locale avec le même nom.

Donc, en général, self in method names est utilisé pour distinguer entre les variables de classe et d'instance, et partout ailleurs vous l'utilisez quand Ruby a besoin d'aide pour distinguer entre les appels de méthode et variables locales ou affectation de variables locales.

J'espère que cela a du sens!

111
répondu Andrew 2013-08-18 00:14:31

Voici un exemple d'utilisation:

def run miles
  self.miles = miles
end

Dans ce cas, l'auto aidera. dans la plupart des cas, self est redondant.

4
répondu Sohan 2011-07-12 19:14:51

Une autre utilisation de self est de déclarer des méthodes de classe (similaires aux méthodes statiques en Java).

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

Cela étant dit, vous auriez également pu utiliser def foo.bar à la place pour la signature de la méthode.

4
répondu brayne 2011-07-12 20:11:01