<commit_before>require "einstein/visitors"

module Einstein
  module Nodes
    # Base class for all Einstein nodes.
    class Node
      include Einstein::Visitors

      # Initializes a new instance of this node with the given +value+.
      def initialize(value)
        @value = value
      end

      # The value of this node.
      attr_accessor :value

      # Implements the visitor pattern by calling a method named
      # visit_SomeNode when visiting a class named SomeNode.  This way we
      # separate the tree traversal logic from the nodes themselves, which
      # makes it easier to modify the visitors, or to add new ones.
      def accept(visitor, &block)
        klass = self.class.ancestors.find do |ancestor|
          visitor.respond_to?("visit_#{ancestor.name.split(/::/)[-1]}")
        end

        if klass
          visitor.send("visit_#{klass.name.split(/::/)[-1]}", self, &block)
        else
          raise "No visitor for '#{self.class}'"
        end
      end

      # Evaluate this node against the given +scope+.  Returns a numeric value
      # calculated by walking the AST with an instance of EvaluateVisitor.
      def evaluate(scope = {})
        EvaluateVisitor.new(scope).accept(self)
      end

      def inspect
        PrettyPrintVisitor.new.accept(self)
      end

      # Returns this node as an s-expression.  Built by walking the AST with
      # an instance of SexpVisitor.
      def to_sexp
        SexpVisitor.new.accept(self)
      end<commit_msg>Added a #to_s method to Einstein::Nodes::Node.<commit_after>require "einstein/visitors"

module Einstein
  module Nodes
    # Base class for all Einstein nodes.
    class Node
      include Einstein::Visitors

      # Initializes a new instance of this node with the given +value+.
      def initialize(value)
        @value = value
      end

      # The value of this node.
      attr_accessor :value

      # Implements the visitor pattern by calling a method named
      # visit_SomeNode when visiting a class named SomeNode.  This way we
      # separate the tree traversal logic from the nodes themselves, which
      # makes it easier to modify the visitors, or to add new ones.
      def accept(visitor, &block)
        klass = self.class.ancestors.find do |ancestor|
          visitor.respond_to?("visit_#{ancestor.name.split(/::/)[-1]}")
        end

        if klass
          visitor.send("visit_#{klass.name.split(/::/)[-1]}", self, &block)
        else
          raise "No visitor for '#{self.class}'"
        end
      end

      # Evaluate this node against the given +scope+.  Returns a numeric value
      # calculated by walking the AST with an instance of EvaluateVisitor.
      def evaluate(scope = {})
        EvaluateVisitor.new(scope).accept(self)
      end

      # Performs a "pretty print" of this node.
      def to_s
        PrettyPrintVisitor.new.accept(self)
      end

      # Also use #to_s for inspecting a node in IRB.
      alias_method :inspect, :to_s

      # Returns this node as an s-expression.  Built by walking the AST with
      # an instance of SexpVisitor.
      def to_sexp
        SexpVisitor.new.accept(self)
      end
{'fraction_non_alphanumeric': 0.08020208399115883, 'fraction_numerical': 0.0012630249447426586, 'mean_word_length': 2.317277486910995, 'pattern_counts': {'":': 0, '<': 3, '<?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': '4784574', 'n_tokens_mistral': 894, 'n_tokens_neox': 879, 'n_words': 325}