Solución:
Hay varios usos importantes, la mayoría de los cuales son básicamente para eliminar la ambigüedad entre métodos de instancia, métodos de clase y variables.
Primero, esta es la mejor manera de definir métodos de clase:
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"
Además, dentro de los métodos de instancia self
hace referencia a la instancia, dentro de los métodos de clase se refiere a la clase y siempre se puede utilizar para distinguir de las 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
Entonces, al final, puedes evitar usar self
en muchos casos, pero a menudo es útil usarlo para asegurarse de no crear inadvertidamente conflictos de nombres más adelante. A veces, estos pueden crear errores que son muy difíciles de encontrar. Al final, suele ser una cuestión de estilo personal.
Como se señaló en los comentarios, una cosa más realmente importante:
En una clase, si tienes un método como este:
def bar=(string)
...
end
Y en otro método llamas:
def other_method
bar = "abcd"
end
No va a llamar a tu bar=
método, va a crear una variable local bar
. Entonces, en este caso usas self
para decirle a Ruby que no cree una variable local:
def other_method
self.bar = "abcd"
end
Lo mismo se aplica si desea tomar un argumento con el nombre de un método:
def example
...
end
def other_thing(example)
self.example(example)
end
Si te dejaste self
Ruby supondría que te refieres a la variable local con el mismo nombre.
Entonces, en general, self
en nombres de métodos se usa para distinguir entre clases y variables de instancia, y en cualquier otro lugar donde Ruby necesita ayuda para distinguir entre llamadas a métodos y variables locales o asignación de variables locales.
Espero que tenga sentido.
En la mayoría de los casos self.foo
de hecho es redundante porque solo puedes escribir foo
para el mismo efecto, pero en este caso no es y el self
es requerido.
var_one = method(args)
creará una variable local llamada var_one
, no llamará a ningún método ni hará nada más para self
.
self.var_one = method(args)
llamará al método var_one=
sobre self
con el argumento method(args)
.
Otro caso donde el uso de self
no es opcional sería si desea pasarlo como un argumento a un método, es decir some_method(self)
– no puedes hacer eso sin el self
palabra clave.
He aquí un ejemplo:
def run miles
self.miles = miles
end
En este caso self
ayudará. En la mayoría de los casos self
es redundante.