2010-02-19 15 views
5

¿Alguien puede ayudarme a dar sentido a lo siguiente? Tengo el siguiente código en test.rb:Método declarado fuera de la clase se incluye automáticamente?

class Dog 
end 
// bark is declared outside of Dog class 
def bark 
    puts 'Woof!' 
end 

después en IRB:

>> source 'test.rb' 
>> a = Dog.new 
=> #<Dog:0x117f614> 
>> a.bark 
Woof! 
=> nil 

¿Por qué método bark existe en la instancia perro a pesar de que se declara fuera de la clase? Porque está en el mismo archivo? ¡Gracias!

Respuesta

3

Cuando se crea un método en el ámbito "global" (fuera de cualquier clase), que el método se realiza un método privado del objeto:

#!/usr/bin/ruby1.8 

class Dog 
end 

p Object.respond_to?(:bark, true)  # => false 

def bark 
    puts "Woof!" 
end 

p Object.respond_to?(:bark, true)  # => true 

Object en la cadena de la ascendencia de todos los objetos, incluyendo Perro:

dog = Dog.new 
p dog.class.name    # => "Dog" 
p dog.class.superclass.name # => "Object" 

Por lo tanto, los perros (y de hecho todos los objetos) ahora saben cómo ladrar. Sin embargo, al ser privado del método, usted tendrá que usar instance_eval llamarlo con un receptor explícito:

dog.instance_eval { bark } # => "Woof!" 

O se le puede llamar con un receptor implícito sin la gimnasia necesaria:

bar # => "Woof!" 
+0

¡Tiene sentido, gracias! – penger

1

Su ejemplo exacto no funciona en Ruby 1.9. (Además de la sintaxis comentario negativo.)

Sin embargo, declarar un método en el ámbito de nivel superior hará que sea un método privado en Object, al parecer:

>> Object.private_methods.include? :bark 
=> true 

Tal vez en su Ruby, (1,8?) este es un método público?

+0

¡Es no es público en 1.8 tampoco. No sé por qué el código del OP no se quejó de que "el ladrido del método privado se llama ...". Tiene algo que ver con la línea "fuente" de IRB. No sé lo que hace diferente de "requerir". –

+0

(En 1.8.7) esto parece ser cierto: si requiero en lugar de la fuente, de hecho obtengo ese error. La fuente es presumiblemente la misma que la Bash incorporada, que incluye el contenido del archivo como si hubiera sido escrito, por lo tanto, se podría acceder a un método privado. – Shadowfirebird

Cuestiones relacionadas