Uso de la palabra clave ruby self?


Por lo que entiendo de la palabra clave self, simplemente se refiere a la instancia actual de la clase. ¿No es este el comportamiento predeterminado en todo momento de todos modos? Por ejemplo, no es

self.var_one = method(args) equivalente a var_one = method(args) ?

Si es así, ¿cuál es el uso del yo?

Author: hagello, 2011-07-12

4 answers

En la mayoría de los casos self.foo es de hecho redundante porque solo se puede escribir foo para el mismo efecto, pero en este caso no lo es y se requiere el self.

var_one = method(args) creará una variable local llamada var_one, no llamará a ningún método ni hará nada más a self.

self.var_one = method(args) llamará al método var_one= en self con el argumento method(args).

Otro caso en el que el uso de self no es opcional sería si desea pasarlo como un argumento a un método, es decir, some_method(self) - usted no se puede hacer eso sin la palabra clave self.

 51
Author: sepp2k,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-12 18:59:44

Hay varios usos importantes, la mayoría de los cuales son básicamente para desambiguar entre métodos de instancia, métodos de clase y variables.

Primero, esta es la mejor manera de definir métodos de clase. IE:

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"

También, dentro de los métodos de instancia self se refiere a la instancia, dentro de los métodos de clase se refiere a la clase, y siempre se puede usar 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

Así que, al final, puede evitar usar self en muchos casos, pero a menudo es útil ir adelante y úselo para asegurarse de que no cree conflictos de nombres inadvertidamente más adelante. A veces pueden crear errores que son muy difíciles de encontrar. Al final, a menudo es una cuestión de estilo personal.


Actualización: 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 se llama:

def other_method
  bar = "abcd"
end

No va a llamar a su método bar=, va a crear una barra de variables locales. Tan, en este caso se usa self para decirle a ruby que no cree una variable local, así:

def other_method
  self.bar = "abcd"
end

Lo mismo se aplica si desea tomar un argumento con el nombre de un método, como así:

def example
  ...
end

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

Si se omite self, se asumirá que se refiere a la variable local con el mismo nombre.

Entonces, en general, self in method names se usa para distinguir entre variables de clase e instancia, y en cualquier otro lugar donde lo use cuando Ruby necesita ayuda para distinguir entre llamadas a métodos y variables locales o asignación de variables locales.

Espero que tenga sentido!

 111
Author: Andrew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-18 00:14:31

Aquí hay un ejemplo de uso:

def run miles
  self.miles = miles
end

En este caso uno mismo ayudará. en la mayoría de los casos el yo es redundante.

 4
Author: Sohan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-12 19:14:51

Otro uso de self es declarar métodos de clase (similar a los métodos estáticos en Java).

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

Dicho esto, también podría haber utilizado def foo.bar en su lugar para la firma del método.

 4
Author: brayne,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-12 20:11:01