2010-12-03 23 views
17

Sé que self es la instancia dentro de un método de instancia. Entonces, ¿es self la clase dentro de un método de clase? Por ejemplo, ¿funcionará lo siguiente en Rails?En Ruby, dentro de un método de clase, ¿es la clase o una instancia?

class Post < ActiveRecord::Base 
    def self.cool_post 
    self.find_by_name("cool") 
    end 
end 
+5

Y para agregar a las respuestas a continuación, ya que el rubí siempre evaluará el receptor como auto menos que se especifique, el código anterior se puede simplemente llamar 'find_by_name 'sin ti mismo :) – brad

+0

Gracias, ¿hay casos en los que sea una buena idea especificar' self'? ¿Es 'self.find_by_name' el primer lugar en el que Ruby buscará' find_by_name'? ¿Se ve en otro lado? ¿Qué tal un método definido globalmente (un método definido en el archivo fuera de una clase)? – ma11hew28

+0

Lo probé. Parece que el orden de precedencia es el método de clase y luego el método globalmente definido si no se encuentra ningún método de clase. – ma11hew28

Respuesta

21

Eso es correcto. self dentro de un método de clase es la clase en sí misma. (. Y también dentro de la definición de clase, tales como el self en def self.coolpost)

Usted puede probar fácilmente estas cositas con el IRB:

class Foo 
    def self.bar 
    puts self.inspect 
    end 
end 

Foo.bar # => Foo 
5
class Test 
    def self.who_is_self 
     p self 
    end 
end 

Test.who_is_self 

de salida:

prueba

Ahora bien, si quieres unos rieles solución específica, se llama named_scopes:

class Post < ActiveRecord::Base 
    named_scope :cool, :conditions => { :name => 'cool' } 
end 

utilizado como esto:

Post.cool 
4

Respuesta corta:

Lo que me gusta hacer con estas preguntas es simplemente iniciar una sesión de irb o ./script/console

y la n puede hacer lo siguiente para ver la magia:

ruby-1.8.7-p174 > class TestTest 
ruby-1.8.7-p174 ?> def self.who_am_i 
ruby-1.8.7-p174 ?> return self 
ruby-1.8.7-p174 ?> end 
ruby-1.8.7-p174 ?> end 
=> nil 
ruby-1.8.7-p174 > TestTest.who_am_i 
=> TestTest 

Happy fishing!

5

Una gran cantidad de respuestas ya, pero aquí es la razón por uno mismo es la clase:

El punto cambia self a lo que está antes del punto. Por lo tanto, cuando lo haga foo.bar, entonces para el bar -metodo, self es foo. No hay diferencia con los métodos de clase. Cuando llame al Post.cool_post, cambiará self a Post.

Lo importante a tener en cuenta aquí es que no es cómo se define el método que determina self, sino cómo se llama. Esto es por qué esto funciona:

class Foo 
    def self.bar 
    self 
    end 
end 

class Baz < Foo 
end 

Baz.bar # => Baz 

O esto:

module Foo 
    def bar 
    self 
    end 
end 

class Baz 
    extend Foo 
end 

Baz.bar # => Baz 
Cuestiones relacionadas