3
\$\begingroup\$
module A
  def methodInA
    # do stuff
    methodInB
    # do stuff
  end
end

module B
  def methodInB
    puts "this is a B method!"
  end
end

class C
  extend A
  extend B

  def initialize
    methodInA
  end
end

c = new C

I'm not feeling good about this. Is this a good idea in general? Any pointers as to where I can learn the best pattern for this?

\$\endgroup\$
  • 2
    \$\begingroup\$ Not a real answer, but a lot of people use ActiveSupport::Concern to manage module dependencies. The linked page has some examples/use cases. \$\endgroup\$ – kardeiz Sep 10 '13 at 16:24
1
\$\begingroup\$

+1 for ActiveSupport::Concern.

As to the best practices, i'd recommend if possible to clearly state dependency of module A on module B :

module A
  include B
  def method_in_a
    method_in_b
  end
end

class C
  include A
end

or :

module A
  def self.included( base )
    base.send :include, B
  end

  def method_in_a
    method_in_b
  end
end

class C
  include A
end

...and that's why ActiveSupport::Concern is cool, because it helps managing such dependencies.

\$\endgroup\$
3
\$\begingroup\$

Since inheritance and interface both has some problems of their own, high level languages like ruby, python supports a different way for organizing code- Mixin.

The code you have written involves mixin, you can see this as interface with implemented methods.When a class can inherit features from more than one parent class, the class is supposed to show multiple inheritance.

Ruby does not suppoprt mutiple inheritance directly but Ruby Modules have another, wonderful use. At a stroke, they pretty much eliminate the need for multiple inheritance, providing a facility called a mixin.

Mixins give you a wonderfully controlled way of adding functionality to classes. However, their true power comes out when the code in the mixin starts to interact with code in the class that uses it.

say we have a module for debugging. we want to use this in many classes and modules. we can just include this debug module to our classes and all methods for debugging will be added in the code as own method of our class.

see the code bellow:

module Debugger
  def log
    #do stuff
    puts "#{Time.now}: This is a log"
  end
end


class C
  include Debugger

  def initialize
    #do stuff
  end

  def run
    #do stuff
    log
  end

end

c =  C.new
c.run
\$\endgroup\$
  • \$\begingroup\$ i think you mean log instead of Debugger.log in run. Otherwise it's a service and no need to include it. \$\endgroup\$ – m_x Sep 18 '13 at 21:11
  • \$\begingroup\$ you are right @m_x, it was a mistake. I have updated the code snippet. thanks :) \$\endgroup\$ – khanmizan Sep 24 '13 at 16:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.