2012-05-25 11 views
7

Ich habe eine Ruby-Klasse, die ein Modul enthält. Ich möchte, dass sich die einschließende Klasse wie OpenStruct verhält. Wie erreiche ich das, ohne explizit von OpenStruct zu erben?Kann ich eine Ruby-Klasse so erweitern, dass sie sich dynamisch wie OpenStruct verhält?

class Book 
    include MyModule 
end 

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

statt

class Book < OpenStruct 
    include MyModule 
end 
+0

Wollen Sie irgendwie OpenStruct Klasse verwenden oder diese Funktionalität selbst implementieren? – Flexoid

+0

Ich möchte OpenStruct verwenden – Sathish

Antwort

7

Sie könnten alle Methoden delegieren Ihre Klasse behandeln nicht zu einer 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

Wenn Sie dies tun, möchten Sie vielleicht die Delegate-Klasse aus der Standardbibliothek betrachten, anstatt Ihre eigene zu rollen: http://www.ruby-doc.org/stdlib-1.9.3/libdoc /delegate/rdoc/index.html –

1

Da OpenStruct kein Modul ist, und Sie können nicht dazu führen, Module von Klassen zu erben, müssen Sie Ihr eigenes Modul schreiben, die method_missing die OpenStruct Fähigkeiten zur Umsetzung verwendet. Zum Glück ist das sehr wenig Arbeit. Die gesamte OpenStruct-Klasse umfasst nur etwa 80 Codezeilen, und die meisten davon benötigen Sie wahrscheinlich nicht einmal vollständig.

Gibt es einen guten Grund, warum Sie sich auf OpenStruct selbst verlassen wollten?