2012-05-25 16 views
7

Tengo una clase de Ruby que incluye un módulo. Quiero que la clase incluida se comporte como OpenStruct. ¿Cómo logro esto sin heredar explícitamente OpenStruct?¿Puedo extender una clase Ruby para que se comporte como OpenStruct dinámicamente?

class Book 
    include MyModule 
end 

module MyModule 
    def self.included(klass) 
    # Make including class behave like OpenStruct 
    end 
end 

en lugar de

class Book < OpenStruct 
    include MyModule 
end 
+0

¿Quieres usar la clase OpenStruct alguna manera o implementar esta funcionalidad por sí mismo? – Flexoid

+0

Quiero usar OpenStruct – Sathish

Respuesta

7

Se podría delegar todos los métodos de la clase no maneja a un OpenStruct:

require 'ostruct' 

class Test_OS 

    def initialize 
    @source = OpenStruct.new 
    end 

    def method_missing(method, *args, &block) 
    @source.send(method, *args, &block) 
    end 

    def own_method 
    puts "Hi." 
    end 

end 

t = Test_OS.new 
t.foo = 1 
p t.foo #=> 1 
t.own_method #=> Hi. 
+1

Si hace esto, puede consultar la clase delegada de la biblioteca estándar en lugar de hacer la suya propia: http://www.ruby-doc.org/stdlib-1.9.3/libdoc /delegate/rdoc/index.html –

1

Desde OpenStruct no es un módulo, y no se puede hacer que los módulos a heredar de clases, tendrá que escribir su propio módulo que utiliza method_missing para implementar las capacidades OpenStruct. Afortunadamente, esto es muy poco trabajo. La clase completa de OpenStruct tiene solo unas 80 líneas de código, y la mayoría de ellas probablemente ni siquiera las necesite por completo.

¿Hay alguna razón importante por la que quiera confiar en OpenStruct?

Cuestiones relacionadas