<commit_before>$LOAD_PATH.unshift File.dirname(__FILE__)

require 'active_record'
require 'acts_as_splittable/splittable'
require 'acts_as_splittable/splitter'
require 'acts_as_splittable/config'

module ActsAsSplittable
  class << self
    DEFAULT_OPTIONS = {
      callbacks:       true,
      predicates:      false,
      join_on_change:  false,
      split_on_change: false,
      allow_nil:       false,
    }

    def default_options(*args)
      case args.length
      when 0
        @default_options ||= DEFAULT_OPTIONS
      when 1
        self.default_options = args.first
      else
        raise ArgumentError, "wrong number of arguments (#{args.length} for 0..1)"
      end
    end

    def default_options=(options)
      default_options.merge! options
    end
  end

  def acts_as_splittable(options = {})
    options = options.reverse_merge ActsAsSplittable.default_options

    extend  ClassMethods
    include Splittable

    self.splittable_options = options

    if splittable_options[:split_on_change]
      include splittable_module
    end

    if splittable_options[:callbacks]
      after_initialize { new_record? or split_column_values! }
      before_save      { join_column_values! }
    end
  end

  def acts_as_hasty_splittable(options = {})
    acts_as_splittable options.reverse_merge(join_on_change: true, split_on_change: true, callbacks: false)
  end

  module ClassMethods
    attr_writer :splittable_options

    def splittable_options
      @splittable_options ||= {}
    end

    def with_splittable_options(other_options = {})
      old = splittable_options
      self.splittable_options = old.merge(other_options)
      Proc.new.(splittable_options)
    ensure
      self.splittable_options = old
    end

    def splittable_config
      @splittable_config ||= Config.new
    end

    def splittable(column, options)
      options  = options.merge(name: column.to_sym)
      splitter = Splitter.new(self, options)

      splittable_config.splitters << splitter

      splitter.attributes.each do |attribute|
        define_splittable_getter(attribute)
        define_splittable_setter(attribute, splitter)
        define_splittable_predicator(attribute) if splitter.predicates?
      end

      if splittable_options[:split_on_change]
        define_splittable_setter_hook(splitter.name)
      end
    end

    def inherited(child)
      super

      child.splittable_options = splittable_options.dup

      if child.splittable_options[:split_on_change]
        child.splittable_module = splittable_module.dup
        child.send(:include, child.splittable_module)
      end
        
      child.splittable_config.inherit! splittable_config
    end

    protected

    attr_writer :splittable_module

    def splittable_module
      @splittable_module ||= Module.new
    end

    private

    def define_splittable_getter(attribute)
      define_method attribute do
        splittable_attributes[attribute]
      end
    end

    def define_splittable_setter(attribute, splitter)
      define_method :"#{attribute}=" do |value|
        splittable_attributes[attribute] = value

        unless splittable_changed_attribute? attribute
          splittable_changed_attributes << attribute
        end

        self.class.with_splittable_options split_on_change: false do |options|
          if options[:join_on_change]
            join_column_values! splitter.name 
          end
        end
      end
    end

    def define_splittable_predicator(attribute)
      define_method :"#{attribute}_changed?" do
        splittable_changed_attribute? attribute
      end
    end

    def define_splittable_setter_hook(name)
      splittable_module.module_eval do
        define_method("#{name}=") do |value|
          if defined?(super)
            super(value)
          elsif respond_to?(:write_attribute, true)
            write_attribute name, value
          end

          self.class.with_splittable_options join_on_change: false do
            split_column_values! name
          end
        end
      end
    end

  end
end

ActiveRecord::Base.extend ActsAsSplittable<commit_msg>define methods in anonymouse module<commit_after>$LOAD_PATH.unshift File.dirname(__FILE__)

require 'active_record'
require 'acts_as_splittable/splittable'
require 'acts_as_splittable/splitter'
require 'acts_as_splittable/config'

module ActsAsSplittable
  class << self
    DEFAULT_OPTIONS = {
      callbacks:       true,
      predicates:      false,
      join_on_change:  false,
      split_on_change: false,
      allow_nil:       false,
    }

    def default_options(*args)
      case args.length
      when 0
        @default_options ||= DEFAULT_OPTIONS
      when 1
        self.default_options = args.first
      else
        raise ArgumentError, "wrong number of arguments (#{args.length} for 0..1)"
      end
    end

    def default_options=(options)
      default_options.merge! options
    end
  end

  def acts_as_splittable(options = {})
    options = options.reverse_merge ActsAsSplittable.default_options

    extend  ClassMethods
    include Splittable
    include splittable_module

    self.splittable_options = options

    if splittable_options[:callbacks]
      after_initialize { new_record? or split_column_values! }
      before_save      { join_column_values! }
    end
  end

  def acts_as_hasty_splittable(options = {})
    acts_as_splittable options.reverse_merge(join_on_change: true, split_on_change: true, callbacks: false)
  end

  module ClassMethods
    attr_writer :splittable_options

    def splittable_options
      @splittable_options ||= {}
    end

    def with_splittable_options(other_options = {})
      old = splittable_options
      self.splittable_options = old.merge(other_options)
      Proc.new.(splittable_options)
    ensure
      self.splittable_options = old
    end

    def splittable_config
      @splittable_config ||= Config.new
    end

    def splittable(column, options)
      options  = options.merge(name: column.to_sym)
      splitter = Splitter.new(self, options)

      splittable_config.splitters << splitter

      splitter.attributes.each do |attribute|
        define_splittable_getter(attribute)
        define_splittable_setter(attribute, splitter)
        define_splittable_predicator(attribute) if splitter.predicates?
      end

      if splittable_options[:split_on_change]
        define_splittable_setter_hook(splitter.name)
      end
    end

    def inherited(child)
      super
      child.splittable_options = splittable_options.dup
      child.splittable_module  = splittable_module.dup
      child.send(:include, child.splittable_module)
      child.splittable_config.inherit! splittable_config
    end

    protected

    attr_writer :splittable_module

    def splittable_module
      @splittable_module ||= Module.new
    end

    private

    def define_splittable_method(name, &block)
      splittable_module.__send__ :define_method, name, &block
    end

    def define_splittable_getter(attribute)
      define_splittable_method attribute do
        splittable_attributes[attribute]
      end
    end

    def define_splittable_setter(attribute, splitter)
      define_splittable_method :"#{attribute}=" do |value|
        splittable_attributes[attribute] = value

        unless splittable_changed_attribute? attribute
          splittable_changed_attributes << attribute
        end

        self.class.with_splittable_options split_on_change: false do |options|
          if options[:join_on_change]
            join_column_values! splitter.name 
          end
        end
      end
    end

    def define_splittable_predicator(attribute)
      define_splittable_method :"#{attribute}_changed?" do
        splittable_changed_attribute? attribute
      end
    end

    def define_splittable_setter_hook(name)
      define_splittable_method "#{name}=" do |value|
        if defined?(super)
          super(value)
        elsif respond_to?(:write_attribute, true)
          write_attribute name, value
        end

        self.class.with_splittable_options join_on_change: false do
          split_column_values! name
        end
      end
    end

  end
end

ActiveRecord::Base.extend ActsAsSplittable
{'fraction_non_alphanumeric': 0.06361756477314195, 'fraction_numerical': 0.0009731176255929935, 'mean_word_length': 2.889309366130558, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 3, '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': '4593606', 'n_tokens_mistral': 2526, 'n_tokens_neox': 2446, 'n_words': 485}