<commit_before># -*- encoding : utf-8 -*-
module Notifier
  class Base
    attr_reader :callback, :observers, :options
    # @param [Symbol] callback callback key to which this observer will respond (:create, :update, :save, :destroy)
    # @param [Array] observers list of observers asssociations in the symbolized-underscored form (SimpleAssociation => :simple_association)
    # @param [Hash] options additional options for the notifier
    # @option options [Class] :observer_class the class of the observer (important when the observer association is polymorphic)
    def initialize(callback, observers, options = {})
      @callback = callback
      @observers = Array(observers)
      @options = options
    end


    # this function will be triggered by the notify_observers call on the observable model. It is basically
    # implemented as a filter where it is seen if the triggered callback corresponds to the callback this observer
    # responds to
    #
    # @param [Array] args [callback: key from the callback that has just been triggered, to_exclude: list of associations to exclude from the notifying chain]
    # @param [Object] observable the object which triggered the callback
    def update(args, observable)
      callback, to_exclude = args
      return unless accepted_callback?(callback)
      observers = self.observers
      observers = observers.reject{|assoc| to_exclude.include?(assoc) }
      observers = observers.select{|assoc| observable.association(assoc).klass == @options[:observer_class] } if @options.has_key?(:observer_class)
      notify(observable, observers.map{|assoc| observable.send(assoc)}.compact)
    end

    # @return [Boolean] whether the action should be executed for the observer
    def conditions(observable, observer) ; true ; end
    # @return [Boolean] whether the action should be executed for the observers collection
    def conditions_many(observable, observers) ; true ; end

    # abstract action; has to be implemented by the subclass
    def action(observable, observer, callback=@callback)
      raise "this has to be implemented in your notifier"
    end



    private

    def accepted_callback?(callback)
      case @callback
        when :save then [:create, :update, :save].include?(callback)
        when :update then [:update, :save].include?(callback)
        else callback == @callback
      end
    end

    # Notifies all observers; filters the observers into two groups: one-to-many and one-to-one collections
    # @param [Object] observable the object which is notifying
    # @param [Array] observers the associated observers which will be notified
    def notify(observable, observers, &block)
      many, ones = observers.partition{|obs| obs.respond_to?(:size) }
      action = block_given? ? block : method(:action)
      notify_many(observable, many, &action)
      notify_ones(observable, ones, &action)
    end

    # TODO: make this notify private as soon as possible again
    public :notify

    # Abstract Method (can be re-defined by other notifiers); here it is defined the default implementation of
    # handling of many-to-many observers: for each one it will notify its observers, in case these are observed
    # @param [Object] observable the object which is notifying
    # @param [Array[ActiveRecord::Relation]] many_observers the observers which will be notified; each element represents a one-to-many relation
    def notify_many(observable, many_observers)
      many_observers.each do |observers|
        AssociationObservers::queue.enqueue_notifications(@callback, observers) do |observer|
          yield(observable, observer) if conditions(observable, observer)
        end if conditions_many(observable, observers)
      end
    end

    # Abstract Method (can be re-defined by other notifiers); here it is defined the default implementation of
    # handling of one-to-one observers: for each one it will notify its observers, in case these are observed
    # @param [Object] observable the object which is notifying
    # @param [Array[Object]] observers the observers which will be notified; each element represents a one-to-one association
    def notify_ones(observable, observers)
      observers.each do |uniq_observer|
        AssociationObservers::queue.enqueue_notifications(@callback, [uniq_observer], :batch_size => 1, :klass => uniq_observer.class) do |observer|
          yield(observable, observer)
        end if conditions(observable, uniq_observer)
      end
    end
  end
end<commit_msg>removed the optional block passed to the notification, thereby locking the procedure passed to the observers to the action method of the notifiers.<commit_after># -*- encoding : utf-8 -*-
module Notifier
  class Base
    attr_reader :callback, :observers, :options
    # @param [Symbol] callback callback key to which this observer will respond (:create, :update, :save, :destroy)
    # @param [Array] observers list of observers asssociations in the symbolized-underscored form (SimpleAssociation => :simple_association)
    # @param [Hash] options additional options for the notifier
    # @option options [Class] :observer_class the class of the observer (important when the observer association is polymorphic)
    def initialize(callback, observers, options = {})
      @callback = callback
      @observers = Array(observers)
      @options = options
    end


    # this function will be triggered by the notify_observers call on the observable model. It is basically
    # implemented as a filter where it is seen if the triggered callback corresponds to the callback this observer
    # responds to
    #
    # @param [Array] args [callback: key from the callback that has just been triggered, to_exclude: list of associations to exclude from the notifying chain]
    # @param [Object] observable the object which triggered the callback
    def update(args, observable)
      callback, to_exclude = args
      return unless accepted_callback?(callback)
      observers = self.observers
      observers = observers.reject{|assoc| to_exclude.include?(assoc) }
      observers = observers.select{|assoc| observable.association(assoc).klass == @options[:observer_class] } if @options.has_key?(:observer_class)
      notify(observable, observers.map{|assoc| observable.send(assoc)}.compact)
    end

    # @return [Boolean] whether the action should be executed for the observer
    def conditions(observable, observer) ; true ; end
    # @return [Boolean] whether the action should be executed for the observers collection
    def conditions_many(observable, observers) ; true ; end

    # abstract action; has to be implemented by the subclass
    def action(observable, observer, callback=@callback)
      raise "this has to be implemented in your notifier"
    end



    private

    def accepted_callback?(callback)
      case @callback
        when :save then [:create, :update, :save].include?(callback)
        when :update then [:update, :save].include?(callback)
        else callback == @callback
      end
    end

    # Notifies all observers; filters the observers into two groups: one-to-many and one-to-one collections
    # @param [Object] observable the object which is notifying
    # @param [Array] observers the associated observers which will be notified
    def notify(observable, observers)
      many, ones = observers.partition{|obs| obs.respond_to?(:size) }
      notify_many(observable, many)
      notify_ones(observable, ones)
    end

    # TODO: make this notify private as soon as possible again
    public :notify

    # Abstract Method (can be re-defined by other notifiers); here it is defined the default implementation of
    # handling of many-to-many observers: for each one it will notify its observers, in case these are observed
    # @param [Object] observable the object which is notifying
    # @param [Array[ActiveRecord::Relation]] many_observers the observers which will be notified; each element represents a one-to-many relation
    def notify_many(observable, many_observers)
      many_observers.each do |observers|
        AssociationObservers::queue.enqueue_notifications(@callback, observers) do |observer|
          action(observable, observer) if conditions(observable, observer)
        end if conditions_many(observable, observers)
      end
    end

    # Abstract Method (can be re-defined by other notifiers); here it is defined the default implementation of
    # handling of one-to-one observers: for each one it will notify its observers, in case these are observed
    # @param [Object] observable the object which is notifying
    # @param [Array[Object]] observers the observers which will be notified; each element represents a one-to-one association
    def notify_ones(observable, observers)
      observers.each do |uniq_observer|
        AssociationObservers::queue.enqueue_notifications(@callback, [uniq_observer], :batch_size => 1, :klass => uniq_observer.class) do |observer|
          action(observable, observer) if conditions(observable, uniq_observer)
        end
      end
    end
  end
end
{'fraction_non_alphanumeric': 0.07595075840844141, 'fraction_numerical': 0.00043965706748735987, 'mean_word_length': 3.809196617336152, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7238716', 'n_tokens_mistral': 2412, 'n_tokens_neox': 2309, 'n_words': 938}