2008-10-02 11 views
9

Imagínese el siguiente módulo de Ruby:¿Cuál es el propósito de los métodos de instancia en Módulos sin clases?

module Foo 
    def inst_method 
    puts "Called Foo.inst_method" 
    end 
    def self.class_method 
    puts "Called Foo.class_method" 
    end 
end 

Obviamente Foo.class_method se puede llamar sin ningún tipo de instancias de clases. Sin embargo, ¿qué está pasando con Foo.inst_method? ¿Es posible llamar al Foo.inst_method sin incluir o extender previamente una clase?

Descargo de responsabilidad: La pregunta no se centra en resolver un problema real. Solo trato de mejorar mi comprensión del sistema de objetos Ruby.

Respuesta

12

El objetivo principal de los métodos de instancia dentro de los módulos es dar esa funcionalidad a las clases que lo incluyen.

"Mezclar en" un módulo de esta manera es más comúnmente utilizado como un método de simulación multiple inheritance, o en otras situaciones donde la herencia no es el paradigma correcto (no es perfecto "es una" relación) pero desea compartir comportamiento. Es una herramienta más para mantener su código DRY.

Un buen ejemplo de esto en el núcleo de Ruby está observando cómo Array y Hash puede tanto ser recorrido y ordenarán, etc. Cada uno de ellos consiguen esta funcionalidad desde el módulo Enumerable (each_with_index, select, reject, sort y más están todos definidos en el módulo incluido, no en las clases).

4

Mi respuesta sería: "no, no puedes llamar a los métodos de instancia del módulo sin extender primera o incluyendo dicho módulo en una clase"

rubí ahora sabe y todo el engaño de programación meta que contiene probablemente es una forma de llamarlo, pero estaría fuera del uso previsto de los módulos

module Tester 
    def inst_meth 
    puts "test inst meth\n" 
    end 

    def self.meth 
    puts "test self meth\n" 
    end 
end 

begin 
    Tester.meth 
rescue; 
    puts $! 
end 
begin 
    Tester.inst_meth 
rescue 
    puts $! 
end 
begin 
    Tester.new.inst_meth 
rescue 
    puts $! 
end 
begin 
    extend Tester 
    inst_meth 
rescue 
    puts $! 
end 
begin 
    include Tester 
    inst_meth 
rescue 
    puts $! 
end 

da

>ruby test.rb 
test self meth 
undefined method `inst_meth' for Tester:Module 
undefined method `new' for Tester:Module 
test inst meth 
test inst meth 
Cuestiones relacionadas