Sha256: 87af0119f70a7cf5b1818288fc7068e6318e08d07a749a344d1444b04a9734cd

Contents?: true

Size: 1.42 KB

Versions: 1

Compression:

Stored size: 1.42 KB

Contents

module AIPP
  module Patcher

    def self.included(klass)
      klass.extend(ClassMethods)
      klass.class_variable_set(:@@patches, {})
    end

    module ClassMethods
      def patches
        class_variable_get(:@@patches)
      end

      def patch(klass, attribute, &block)
        (patches[self] ||= []) << [klass, attribute, block]
      end
    end

    def attach_patches
      parser = self
      verbose_info_method = method(:verbose_info)
      self.class.patches[self.class]&.each do |(klass, attribute, block)|
        klass.instance_eval do
          alias_method :"original_#{attribute}=", :"#{attribute}="
          define_method(:"#{attribute}=") do |value|
            error = catch :abort do
              value = block.call(parser, self, value)
              verbose_info_method.call("Patching #{self.inspect} with #{attribute}=#{value.inspect}", color: :magenta)
            end
            fail "patching #{self.inspect} with #{attribute}=#{value.inspect} failed: #{error}" if error
            send(:"original_#{attribute}=", value)
          end
        end
      end
      self
    end

    def detach_patches
      self.class.patches[self.class]&.each do |(klass, attribute, _)|
        klass.instance_eval do
          remove_method :"#{attribute}="
          alias_method :"#{attribute}=", :"original_#{attribute}="
          remove_method :"original_#{attribute}="
        end
      end
      self
    end

  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
aipp-1.0.0 lib/aipp/patcher.rb