<commit_before>module Rabl
  class Engine
    # Constructs a new ejs engine based on given vars, handler and declarations
    # Rabl::Engine.new("...source...", { :format => "xml", :root => true, :view_path => "/path/to/views" })
    def initialize(source, options={})
      @_source = source
      @_options = options.reverse_merge(:format => "json")
    end

    # Renders the representation based on source, object, scope and locals
    # Rabl::Engine.new("...source...", { :format => "xml" }).render(scope, { :foo => "bar", :object => @user })
    def render(scope, locals, &block)
      @_locals = locals
      @_scope = scope
      @_options = @_options.merge(:scope => @_scope, :locals => @_locals, :engine => self)
      self.copy_instance_variables_from(@_scope, [:@assigns, :@helpers])
      @_data = locals[:object] || self.default_object
      instance_eval(@_source) if @_source.present?
      instance_eval(&block) if block_given?
      self.send("to_" + @_options[:format].to_s)
    end

    # Returns a hash representation of the data object
    # to_hash(:root => true)
    def to_hash(options={})
      object = @_data.respond_to?(:each_pair) ? @_data.keys.first : @_data
      if is_record?(object) # object @user
        Rabl::Builder.new(@_data, @_options).to_hash(options)
      elsif object.respond_to?(:each) # collection @users
        object.map { |object| Rabl::Builder.new(object, @_options).to_hash(options) }
      end
    end

    # Returns a json representation of the data object
    # to_json(:root => true)
    def to_json(options={})
      options = options.reverse_merge(:root => true)
      to_hash(options).to_json
    end

    # Returns a json representation of the data object
    # to_xml(:root => true)
    def to_xml(options={})
      options = options.reverse_merge(:root => false)
      to_hash(options).to_xml(:root => model_name(@_data))
    end

    # Sets the object to be used as the data source for this template
    # object(@user)
    # object @user => :person
    # object @users
    def object(data)
      @_data = data unless @_locals[:object]
    end
    alias_method :collection, :object

    # Indicates an attribute or method should be included in the json output
    # attribute :foo, :as => "bar"
    # attribute :foo => :bar
    def attribute(*args)
      if args.first.is_a?(Hash)
        args.first.each_pair { |k,v| self.attribute(k, :as => v) }
      else # array of attributes
        options = args.extract_options!
        @_options[:attributes] ||= {}
        args.each { |name| @_options[:attributes][name] = options[:as] || name }
      end
    end
    alias_method :attributes, :attribute

    # Creates an arbitrary code node that is included in the json output
    # code(:foo) { "bar" }
    # code(:foo, :if => lambda { ... }) { "bar" }
    def code(name, options={}, &block)<commit_msg>Collection method should kick the object into an array<commit_after>module Rabl
  class Engine
    # Constructs a new ejs engine based on given vars, handler and declarations
    # Rabl::Engine.new("...source...", { :format => "xml", :root => true, :view_path => "/path/to/views" })
    def initialize(source, options={})
      @_source = source
      @_options = options.reverse_merge(:format => "json")
    end

    # Renders the representation based on source, object, scope and locals
    # Rabl::Engine.new("...source...", { :format => "xml" }).render(scope, { :foo => "bar", :object => @user })
    def render(scope, locals, &block)
      @_locals = locals
      @_scope = scope
      @_options = @_options.merge(:scope => @_scope, :locals => @_locals, :engine => self)
      self.copy_instance_variables_from(@_scope, [:@assigns, :@helpers])
      @_data = locals[:object] || self.default_object
      instance_eval(@_source) if @_source.present?
      instance_eval(&block) if block_given?
      self.send("to_" + @_options[:format].to_s)
    end

    # Returns a hash representation of the data object
    # to_hash(:root => true)
    def to_hash(options={})
      object = @_data.respond_to?(:each_pair) ? @_data.keys.first : @_data
      if is_record?(object) # object @user
        Rabl::Builder.new(@_data, @_options).to_hash(options)
      elsif object.respond_to?(:each) # collection @users
        object.map { |object| Rabl::Builder.new(object, @_options).to_hash(options) }
      end
    end

    # Returns a json representation of the data object
    # to_json(:root => true)
    def to_json(options={})
      options = options.reverse_merge(:root => true)
      to_hash(options).to_json
    end

    # Returns a json representation of the data object
    # to_xml(:root => true)
    def to_xml(options={})
      options = options.reverse_merge(:root => false)
      to_hash(options).to_xml(:root => model_name(@_data))
    end

    # Sets the object to be used as the data source for this template
    # object(@user)
    # object @user => :person
    # object @users
    def object(data)
      @_data = data unless @_locals[:object]
    end

    # Sets the object as a collection casted to a simple array
    # collection @users
    def collection(data)
      object(data.to_a)
    end

    # Indicates an attribute or method should be included in the json output
    # attribute :foo, :as => "bar"
    # attribute :foo => :bar
    def attribute(*args)
      if args.first.is_a?(Hash)
        args.first.each_pair { |k,v| self.attribute(k, :as => v) }
      else # array of attributes
        options = args.extract_options!
        @_options[:attributes] ||= {}
        args.each { |name| @_options[:attributes][name] = options[:as] || name }
      end
    end
    alias_method :attributes, :attribute

    # Creates an arbitrary code node that is included in the json output
    # code(:foo) { "bar" }
    # code(:foo, :if => lambda { ... }) { "bar" }
    def code(name, options={}, &block)
{'fraction_non_alphanumeric': 0.14001361007145288, 'fraction_numerical': 0.0, 'mean_word_length': 3.023956194387406, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 10}, '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': '872857', 'n_tokens_mistral': 1819, 'n_tokens_neox': 1802, 'n_words': 507}