2016-04-27 6 views
0

У меня есть вариант использования, где у меня есть class A, который включает в себя 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 

Как было показано выше, я звоню do_one_thing от do_another_thing. Моя проблема в том, что мне нужно вызвать метод модуля (т. Е. Метод super). Возможно ли это в Rails?

+1

Возможный дубликат [рубинового супер ключевое слово] (http://stackoverflow.com/questions/2597643/ruby-super-keyword) – Hamms

ответ

1

Для использования в использовании метода included, вам понадобится ваш B модуль extend ActiveSupport::Concern, но это не даст вам поведения, которое вы хотите.

Если на вашем месте я бы отказаться от этого шаблона и использовать простые родные Рубиновые модуль модели:

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 

Приведенный выше код будет правильно использовать модуль наследования, который вы ищете.

Read more about Ruby module inheritance here

+0

Спасибо! И извините за мой поздний ответ. Проблема в том, что мне нужно вызвать только метод модуля (без запуска метода класса). В других случаях мне нужно вызвать только метод класса, не запуская метод модуля ... –

+0

У вас есть несколько вариантов. Похоже, что вы действительно хотите, это два метода, которые можно назвать в разных местах. Если этого недостаточно, вы можете попытаться использовать уточнения. Уточнения сходны с патчами обезьян, но имеют гораздо более ограниченный объем влияния. Я написал сообщение о [использовании Ruby Refinements] (http://jakeyesbeck.com/2015/12/13/ruby-refinements/), которое может быть полезным введением. – yez

0

Вы можете 'сохранить' включен метод перед переопределения

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