Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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
like image 385
Sathish Avatar asked May 25 '12 19:05

Sathish


2 Answers

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.
like image 144
steenslag Avatar answered Nov 05 '22 12:11

steenslag


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?

like image 42
Phrogz Avatar answered Nov 05 '22 11:11

Phrogz