d'après ce que je comprends du mot clé self
, il fait simplement référence à 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'utilité de soi?
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, il ne l'est pas et le self
est requis.
var_one = method(args)
créera une variable locale appelée var_one
, elle n'appellera aucune méthode ni ne fera rien d'autre à self
.
self.var_one = method(args)
appellera la méthode var_one=
sur self
avec l'argument method(args)
.
Un autre cas où l'utilisation de self
n'est pas facultative serait si vous voulez le passer comme argument à une méthode, c'est-à-dire some_method(self)
- vous ne pouvez pas le faire sans self
mot clé.
Il existe plusieurs utilisations importantes, dont la plupart consistent essentiellement à lever l'ambiguïté 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 les 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 fait référence à l'instance, dans les méthodes de classe, elle fait référence à la classe, et elle peut toujours être utilisée pour faire la distinction avec les 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 de continuer et de l'utiliser pour vous assurer de ne pas créer par inadvertance des conflits de dénomination plus tard. Parfois, ceux-ci peuvent créer des bogues très difficiles à trouver. En fin de compte, c'est souvent une question de style personnel.
Mise à jour: Comme indiqué dans les commentaires, une autre chose vraiment importante:
Dans une classe, si vous avez une méthode comme celle-ci:
def bar=(string)
...
end
Et dans une autre méthode que 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. Donc, 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 vous étiez arrêté, cela supposerait que vous vouliez dire la variable locale du même nom.
Ainsi, en général, les noms de méthode self in sont utilisés pour distinguer les variables de classe et d'instance, et partout où vous l'utilisez lorsque Ruby a besoin d'aide pour distinguer les appels de méthode des variables locales ou l'affectation des variables locales.
J'espère que cela à du sens!
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.
voici un exemple d'utilisation:
def run miles
self.miles = miles
end
Dans ce cas, l'auto vous aidera. dans la plupart des cas, l'auto est redondant.