2011-01-15 15 views
36

Esto no es específico de Rails: solo estoy usando Rails como ejemplo.Cuándo usar `self.foo` en lugar de` foo` en los métodos de Ruby

que tienen un modelo en Rails:

class Item < ActiveRecord::Base 

    def hello 
    puts "Hello, #{self.name}" 
    end 
end 

(Digamos que el modelo Item (clase) tiene un método llamado name). ¿Cuándo debo usar self.name y cuándo puedo usar name? (Ej. #{name})

+0

Esta es una pregunta que me hace tropezar también. – sevenseacat

Respuesta

56
  1. Es idiomática a prefieren omitir self. al invocar métodos; generalmente nunca es necesario.

  2. Usted necesidad uso self.foo = xxx cuando se llama a un método de selección, en lugar de foo = xxx, por lo que Ruby se da cuenta de que no está intentando crear una nueva variable local.

    • Del mismo modo, en el caso improbable de que tiene una variable local existente do_something con el mismo nombre que un método, debe utilizar self.do_something para invocar el método, como se acaba de do_something va a terminar la lectura de la variable.
  3. Usted no puede uso self.foo(...) para llamar a un método privado; en su lugar, debe llamar al foo(...).

0

Siguiendo this tutorial, usted no tiene ninguna necesidad de utilizar auto puntero. Pero creo que este (o auto en nuestro caso) los punteros se utilizan para resolver conflictos de nombres. En realidad, @name y self.name son las mismas declaraciones (si no hay un método name para su clase). Ej .:

class Moo 
    attr_accessor :name 

    def moo(name) 
    name = name # O_o which *name* should i use? 
    end 

    def foo(name) 
    @name = name # the same as *self.name = name* 
    end 

    def hello 
    puts self.name # the same as *puts @name* 
    end 
end 

a = Moo.new 
a.hello() # should give no output 

a.moo('zaooza') 
a.hello() # Hey! Why does it prints nothing? 

a.foo('zaooza') 
a.hello() # whoa! This one shows 'zaooza'! 

intente ejecutar este código y verás =)

+4

También un caso especial: los métodos denominados 'foo =' DEBEN invocarse mediante 'self.foo =', de lo contrario, define una nueva variable llamada 'foo'. –

+0

Sí, tienes razón. Lo siento, lo he pasado por alto y olvidé por completo de los operadores ... – shybovycha

+5

'@ name' y' self.name' son definitivamente * no * la misma declaración. 'self.name' es una llamada a método y' @ name' es una variable de instancia. Es solo que en su ejemplo (pero no en los OP), 'self.name' es un método que le devuelve' @ name'. En el ejemplo del OP "self".name' obtendrá el valor almacenado en la base de datos y '@ name' simplemente será' nil', por lo que definitivamente no es lo mismo. – sepp2k

10

Si omite self Rubí buscará primero las variables locales con ese nombre, a continuación, por un método de instancia. No es idiomático escribir self.. En cualquier caso, debe escribir self.something = value en las asignaciones.

Tenga en cuenta que no se puede utilizar cuando se llama a self métodos privados (no hay problema con los métodos protegidos):

class A 
    def foo; self.bar; end 

private 

    def bar; "bar"; end 
end 

A.new.foo 
# private method `bar' called for #<A:0x7f49193584f0> (NoMethodError) 
Cuestiones relacionadas