Наследование до или после подключения к дочерним классам - PullRequest
0 голосов
/ 27 ноября 2018

Я написал модуль для подключения методов до или после вызова метода экземпляра.Я хотел бы применить эти хуки ко всем классам, которые наследуются от родительского класса.Однако, если я напишу хук в родительском классе, он не будет выполнен, он будет выполнен, только если он присутствует в дочернем классе.

Это модуль для создания хуков:

module Hooks

def self.included(base)
 base.send :extend, ClassMethods
end


module ClassMethods
  # everytime we add a method to the class we check if we must redifine it
  def method_added(method)
    if @hooker_before && (@methods_to_hook_before.include?(method)|| @methods_to_hook_after.include?(method)) && !@methods_seen.include?(method)
      hooked_method_before = instance_method(@hooker_before) if @hooker_before
      hooked_method_after =  instance_method(@hooker_after) if @hooker_after
      @methods_to_hook_before.each do |method_name|
        begin
          method_to_hook = instance_method(method_name)
        rescue NameError => e
          return
        end
        @methods_seen.push(method)

        define_method(method_name) do |*args, &block|
          hooked_method_before.bind(self).call if hooked_method_before
          method_to_hook.bind(self).(*args, &block) ## your old code in the method of the class
          hooked_method_after.bind(self).call if hooked_method_after
        end
      end
     end
   end

  def before(*methods_to_hook, hookers)
   @methods_to_hook_before = methods_to_hook
   @methods_to_hook_after = [] unless @methods_to_hook_after
   @hooker_before = hookers[:call]
   @methods_seen = []
  end

  def after(*methods_to_hook, hookers)
    @methods_to_hook_after = methods_to_hook
    @methods_to_hook_before = [] unless @methods_to_hook_before
    @hooker_after = hookers[:call]
    @methods_seen = []
  end
 end
end

module Utilities
  def before_generate
    puts("in before generate utilities")
  end
end

class Parent
  include Utilities
  include Hooks


  def generate
    puts("in generate Parent")
  end
end

class Child < Parent
  before :generate, call: :before_generate

  def generate
    puts("in child generate")
  end
end
class AnotherChild < Parent
      before :generate, call: :before_generate

      def generate
        puts("in child generate")
      end
    end

Child.new.generate() выдает желаемый результат: перед генерацией утилит в дочерней генерации. Однако я бы хотел, чтобы все классы, которые наследуются от Parent, автоматически наследовали от этого поведения.Добавление before :generate, call: :before_generate в родительский класс не поможет.Есть ли способ обернуть все дочерние классы в одном модуле?Есть ли способ достичь этого или я должен воспроизвести вызов before в каждом отдельном дочернем классе, где я этого хочу.

1 Ответ

0 голосов
/ 27 ноября 2018

Вы можете использовать наследуемые переменные экземпляра класса для ловушек, чтобы сделать их доступными в дочерних классах, как описано здесь .

...