<commit_before>module JsonParser::ClassMethods
  def json_parse(*attr_names)
    options = {
      path: nil,
      json: :json,
      full_path: nil,
      cached: false,
      class: nil,
      compact: false,
      after: nil,
      case: :lower_camel
    }.merge(attr_names.extract_options!)

    builder = Builder.new(attr_names, self, options)
    builder.build
  end

  class Builder
    attr_reader :attr_names, :options, :methods_def

    def initialize(attr_names, instance, options)
      @attr_names = attr_names
      @instance = instance
      @options = options
      @methods_def = []
      init
    end

    def build
      methods_def.each do |method_def|
        @instance.module_eval(method_def, __FILE__, __LINE__ + 1)
      end
    end

    private

    def init
      attr_names.each do |attr|
        add_attr(attr)
      end
    end

    def path
      options[:path]
    end

    def json_name
      options[:json]
    end

    def full_path(attribute)
      options[:full_path] || [path, attribute].compact.join('.')
    end

    def cached
      options[:cached]
    end

    def clazz
      options[:class]
    end

    def compact
      options[:compact]
    end

    def after
      options[:after] ? ":#{options[:after]}" : false
    end

    def case_type
      options[:case]
    end

    def add_attr(attribute)
      @methods_def << <<-CODE
        def #{attribute}
          #{cached ? cached_fetcher(attribute) : attr_fetcher(attribute)}
        end
      CODE
    end

    def attr_fetcher(attribute)
      <<-CODE
        JsonParser::Fetcher.new(
          #{json_name}, '#{full_path(attribute)}', {
            instance: self,
            clazz: #{clazz || 'nil'},
            compact: #{compact || 'false'},
            after: #{after},
            case_type: :#{case_type}
          }
        ).fetch
      CODE
    end

    def cached_fetcher(attribute)
      <<-CODE
        @#{attribute} ||= #{attr_fetcher(attribute)}
      CODE
    end
  end
end
<commit_msg>Use openstruct and delegate for better code<commit_after>module JsonParser::ClassMethods

  def json_parse(*attr_names)
    options = {
      path: nil,
      json: :json,
      full_path: nil,
      cached: false,
      class: nil,
      compact: false,
      after: nil,
      case: :lower_camel
    }.merge(attr_names.extract_options!)

    builder = Builder.new(attr_names, self, options)
    builder.build
  end

  class Builder
    attr_reader :attr_names, :options, :methods_def

    delegate :path, :cached, :compact, to: :options_object

    def initialize(attr_names, instance, options)
      @attr_names = attr_names
      @instance = instance
      @options = options
      @methods_def = []
      init
    end

    def build
      methods_def.each do |method_def|
        @instance.module_eval(method_def, __FILE__, __LINE__ + 1)
      end
    end

    private

    def options_object
      @options_object ||= OpenStruct.new options
    end

    def init
      attr_names.each do |attr|
        add_attr(attr)
      end
    end

    def json_name
      options[:json]
    end

    def full_path(attribute)
      options[:full_path] || [path, attribute].compact.join('.')
    end

    def clazz
      options[:class]
    end

    def after
      options[:after] ? ":#{options[:after]}" : false
    end

    def case_type
      options[:case]
    end

    def add_attr(attribute)
      @methods_def << <<-CODE
        def #{attribute}
          #{cached ? cached_fetcher(attribute) : attr_fetcher(attribute)}
        end
      CODE
    end

    def attr_fetcher(attribute)
      <<-CODE
        JsonParser::Fetcher.new(
          #{json_name}, '#{full_path(attribute)}', {
            instance: self,
            clazz: #{clazz || 'nil'},
            compact: #{compact || 'false'},
            after: #{after},
            case_type: :#{case_type}
          }
        ).fetch
      CODE
    end

    def cached_fetcher(attribute)
      <<-CODE
        @#{attribute} ||= #{attr_fetcher(attribute)}
      CODE
    end
  end
end

{'fraction_non_alphanumeric': 0.1072929542645241, 'fraction_numerical': 0.0004944375772558715, 'mean_word_length': 2.039819684447784, 'pattern_counts': {'":': 2, '<': 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': '4502640', 'n_tokens_mistral': 1267, 'n_tokens_neox': 1230, 'n_words': 296}