2012-05-25 12 views
7

Mam klasę Ruby, która zawiera moduł. Chcę, aby klasa włączająca zachowywała się jak OpenStruct. Jak osiągnąć to bez jawnego dziedziczenia z OpenStruct?Czy mogę rozszerzyć klasę Ruby, aby zachowywać się dynamicznie jak OpenStruct?

class Book 
    include MyModule 
end 

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

zamiast

class Book < OpenStruct 
    include MyModule 
end 
+0

Chcesz użyć klasy OpenStruct jakiś sposób wdrożenia tej funkcji przez siebie? – Flexoid

+0

Chcę użyć OpenStruct – Sathish

Odpowiedz

7

Można przekazać wszystkie metody klasa nie obsługuje do 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

Jeśli to zrobisz, możesz chcieć spojrzeć na klasę delegatów ze standardowej biblioteki zamiast na własną rękę: http://www.ruby-doc.org/stdlib-1.9.3/libdoc /delegate/rdoc/index.html –

1

Od OpenStruct nie jest modułem, a nie można spowodować moduły dziedziczyć z klas, trzeba będzie napisać własny moduł, który używa method_missing wdrożyć możliwości OpenStruct. Na szczęście to bardzo mało pracy. Cała klasa OpenStruct to tylko około 80 linii kodu, a większość z tego prawdopodobnie nie jest nawet w pełni potrzebna.

Czy istnieje silny powód, dla którego chciałbyś polegać na samym OpenStruct?