Search code examples
rubymodulemetaprogrammingmixinsopenstruct

Can i extend a Ruby class to behave like OpenStruct dynamically?


I have a Ruby class which includes a module. I want the including class to behave like OpenStruct. How do i achieve this without explicitly inheriting from OpenStruct?

class Book
  include MyModule
end

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

instead of

class Book < OpenStruct
  include MyModule
end

Solution

  • You could delegate all methods your class does not handle to an 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.