1

I have a use case where I have class A which includes module B.

class A
  include B

  def do_one_thing
    # override module's method. do something different instead
  end

  def do_another_thing
    # Call `do_one_thing` from here,
    # but call the module's method, not the one I overrode above.
  end
end

module B
  included do
    def do_one_thing
      # ...
    end
  end

  # some other methods
end

As shown above, I'm calling do_one_thing from do_another_thing. My problem is that I need to call the module's method (i.e. the super method). Is this possible in Rails?

Petr Gazarov
  • 3,602
  • 2
  • 20
  • 37
  • 1
    Possible duplicate of [ruby super keyword](http://stackoverflow.com/questions/2597643/ruby-super-keyword) – Hamms Apr 27 '16 at 22:17

2 Answers2

2

To property use the included method, you'll need your B module to extend ActiveSupport::Concern but that won't give you the behaviour you want.

If I were you I'd abandon that pattern and use simple native Ruby module patterns:

module B    
  def do_one_thing
    puts 'in module'
    # ...
  end

  # some other methods
end

class A
  include B

  def do_one_thing  
    super  
    puts 'in class'
    # override module's method. do something different instead
  end

  def do_another_thing
    do_one_thing
    # Call `do_one_thing` from here,
    # but call the module's method, not the one I overrode above.
  end
end

A.new.do_one_thing

The above code will correctly use the module inheritance you are looking for.

Read more about Ruby module inheritance here

yez
  • 2,368
  • 9
  • 15
  • Thank you! And sorry for my late answer. The problem with this is that I need to call only the module's method (without running the class's method). On other occassions, I need to call only the class method, without running the module's method... – Petr Gazarov May 22 '16 at 16:21
  • You have a few options. What it sounds like you really want is two methods that can be called in different places. If that is not enough, you might try to use Refinements. Refinements are similar to monkey patches but have a much more limited scope of influence. I wrote a post about [using Ruby Refinements](http://jakeyesbeck.com/2015/12/13/ruby-refinements/) that might be a helpful introduction. – yez May 24 '16 at 18:09
0

You can 'save' included method before override

module B
  extend ActiveSupport::Concern

  included do
    def do_one_thing
      puts 'do_one_thing'
    end
  end
end

class A
  include B

  alias_method :old_do_one_thing, :do_one_thing
  def do_one_thing
    puts "I'd rather do this"
  end

  def do_another_thing
    old_do_one_thing
  end
end

a= A.new
a.do_one_thing
a.do_another_thing
Thomas
  • 1,613
  • 8
  • 8