<commit_before>require 'hashie'
require 'singleton'

module OmfEc
  # Experiment class to hold relevant state information
  #
  class Experiment
    include Singleton

    attr_accessor :name, :oml_uri, :app_definitions, :property
    attr_reader :groups, :sub_groups, :state

    def initialize
      @id = Time.now.utc.iso8601
      @property ||= Hashie::Mash.new
      @state ||= []
      @groups ||= []
      @events ||= []
      @app_definitions ||= Hash.new
      @sub_groups ||= []
    end

    def resource(id)
      @state.find { |v| v[:uid] == id }
    end

    def add_resource(name, opts = {})
      unless resource(name)
        @state << Hashie::Mash.new({ uid: name }.merge(opts))
      end
    end

    def sub_group(name)
      @sub_groups.find { |v| v == name }
    end

    def add_sub_group(name)
      @sub_groups << name unless @sub_groups.include?(name)
    end

    def group(name)
      groups.find { |v| v.name == name }
    end

    def add_group(group)
      raise ArgumentError, "Expect Group object, got #{group.inspect}" unless group.kind_of? OmfEc::Group
      @groups << group unless group(group.name)
    end

    def each_group(&block)
      groups.each { |g| block.call(g) } if block
    end

    def all_groups?(&block)
      !groups.empty? && groups.all? { |g| block ? block.call(g) : g }
    end

    def event(name)
      @events.find { |v| v[:name] == name }
    end

    def add_event(name, trigger)
      raise RuntimeError, "Event '#{name}' has been defined" if event(name)
      @events << { name: name, trigger: trigger }
    end

    # Unique experiment id
    def id
      @name.nil? ? @id : "#{@name}-#{@id}"
    end

    # Parsing user defined events, checking conditions against internal state, and execute callbacks if triggered
    def process_events
      EM.next_tick do<commit_msg>Fix v5 odel all_groups.exec<commit_after>require 'hashie'
require 'singleton'

module OmfEc
  # Experiment class to hold relevant state information
  #
  class Experiment
    include Singleton

    attr_accessor :name, :oml_uri, :app_definitions, :property
    attr_reader :groups, :sub_groups, :state

    def initialize
      @id = Time.now.utc.iso8601
      @property ||= Hashie::Mash.new
      @state ||= []
      @groups ||= []
      @events ||= []
      @app_definitions ||= Hash.new
      @sub_groups ||= []
    end

    def resource(id)
      @state.find { |v| v[:uid] == id }
    end

    def add_resource(name, opts = {})
      unless resource(name)
        @state << Hashie::Mash.new({ uid: name }.merge(opts))
      end
    end

    def sub_group(name)
      @sub_groups.find { |v| v == name }
    end

    def add_sub_group(name)
      @sub_groups << name unless @sub_groups.include?(name)
    end

    def group(name)
      groups.find { |v| v.name == name }
    end

    def add_group(group)
      raise ArgumentError, "Expect Group object, got #{group.inspect}" unless group.kind_of? OmfEc::Group
      @groups << group unless group(group.name)
    end

    def each_group(&block)
      if block
        groups.each { |g| block.call(g) }
      else
        groups
      end
    end

    def all_groups?(&block)
      !groups.empty? && groups.all? { |g| block ? block.call(g) : g }
    end

    def event(name)
      @events.find { |v| v[:name] == name }
    end

    def add_event(name, trigger)
      raise RuntimeError, "Event '#{name}' has been defined" if event(name)
      @events << { name: name, trigger: trigger }
    end

    # Unique experiment id
    def id
      @name.nil? ? @id : "#{@name}-#{@id}"
    end

    # Parsing user defined events, checking conditions against internal state, and execute callbacks if triggered
    def process_events
      EM.next_tick do
{'fraction_non_alphanumeric': 0.12566988210075028, 'fraction_numerical': 0.002411575562700965, 'mean_word_length': 2.5150659133709983, 'pattern_counts': {'":': 0, '<': 19, '<?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': '7534411', 'n_tokens_mistral': 1243, 'n_tokens_neox': 1206, 'n_words': 335}