8

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
Sathish
  • 20,660
  • 24
  • 63
  • 71

2 Answers2

10

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.
steenslag
  • 79,051
  • 16
  • 138
  • 171
  • 4
    If you do this, you might want to look at the delegate class from the standard library instead of rolling your own: http://www.ruby-doc.org/stdlib-1.9.3/libdoc/delegate/rdoc/index.html – Michael Kohl May 25 '12 at 22:45
1

Since OpenStruct is not a module, and you cannot cause modules to inherit from classes, you will need to write your own module that uses method_missing to implement the OpenStruct capabilities. Thankfully, this is very little work. The entire OpenStruct class is only about 80 lines of code, and most of that you probably don't even fully need.

Is there a strong reason you wanted to rely on OpenStruct itself?

Phrogz
  • 296,393
  • 112
  • 651
  • 745