<commit_before>my class IO::CatHandle is IO::Handle {
    has @!handles;
    has IO::Handle $!active-handle;

    has $.path;
    has $.chomp is rw;
    has $.nl-in;
    has str $.encoding;

    method !SET-SELF (@!handles, $!chomp, $!nl-in, $!encoding) {
        self.next-handle;
        self
    }
    method new (*@handles, :$pre-open-all,
        :$chomp = True, :$nl-in = ["\x0A", "\r\n"], :$encoding = 'utf8',
    ) {
        if $pre-open-all {
            for @handles {
                when IO::Handle {
                    next if .opened;
                    $_ = .open: :r, :$chomp, :$nl-in, :$encoding orelse .throw;
                }
                $_ = .IO.open: :r, :$chomp, :$nl-in, :$encoding orelse .throw;
            }
        }
        self.bless!SET-SELF(@handles, $chomp, $nl-in, $encoding)
    }
    method next-handle {
      # Set $!active-handle to the next handle in line, opening it if necessary
      nqp::stmts(
        nqp::if(
          nqp::defined($!active-handle),
          ($ = $!active-handle.close)), # don't sink the result, since it might
          # .. be an IO::Pipe that returns a Proc that might throw
        nqp::if(
          @!handles,
          nqp::if(
            nqp::istype(($_ := @!handles.shift), IO::Handle),
            nqp::if(
              .opened,
              ($!active-handle = $_),
              nqp::if(
                nqp::istype(
                  ($_ = .open: :r, :$!chomp, :$!nl-in, :$!encoding),
                  Failure),
                .throw,
                ($!active-handle = $_))),
            nqp::if(
              nqp::istype(($_ := .IO.open: :r, :$!chomp, :$!nl-in, :$!encoding),
                Failure),
              .throw,
              ($!active-handle = $_))),
          ($!active-handle = Nil)))
    }

    # Produce a Seq with an iterator that walks through all handles
    method comb (::?CLASS:D: |c) {}
    method split (::?CLASS:D: |c) {}
    method words (::?CLASS:D: |c) {}

    method !LINES {
      nqp::if(
        nqp::defined($!active-handle),
        (flat $!active-handle.lines, gather {
          nqp::while(
            nqp::defined(self.next-handle),
            take $!active-handle.lines)}),
        Seq.new: Rakudo::Iterator.Empty)
    }
    multi method lines(::?CLASS:D \SELF: $limit, :$close) {
        nqp::istype($limit,Whatever) || $limit == Inf
          ?? self.lines(:$close)
          !! $close
            ?? Seq.new(Rakudo::Iterator.FirstNThenSinkAll(
                self!LINES.iterator, $limit.Int, {SELF.close}))
            !! self.lines.head($limit.Int)
    }
    multi method lines(::?CLASS:D \SELF: :$close) {
      $close # use -1 as N in FirstNThenSinkAllSeq to get all items
        ?? Seq.new(Rakudo::Iterator.FirstNThenSinkAll(
            self!LINES.iterator, -1, {SELF.close}))
        !! self!LINES
    }
    multi method lines(::?CLASS:D:) { self!LINES }

    method Supply (::?CLASS:D: |c) {}

    # Get a single result, going to the next handle on EOF
    method get (::?CLASS:D: |c) {}
    method getc (::?CLASS:D: |c) {}
    method read (::?CLASS:D: |c) {}
    method readchars (::?CLASS:D: |c) {}

    # Walk through all handles, producing single result
    method slurp (::?CLASS:D: |c) {

    }
    method slurp-rest (|) {
        # We inherit deprecated .slurp-rest from IO::Handle. Pull the
        # plug on it in this class, since no one is using this yet.
        # The old IO::ArgFiles used .slurp
        die X::Obsolete.new: :old<slurp-rest>, :new<slurp>,
            :when('with IO::CatHandle')
    }
    method DESTROY {
        try .close for @!handles
    }

    # Call on current handle and do NOT switch to the next one
    method close    {}
    method encoding {}
    method eof      {}
    method gist     {}
    method Str      {}
    method IO       {}
    method path     {}
    method open     {}
    method opened   {}
    method lock     {}<commit_msg>[io grant] Implement IO::CatHandle.close<commit_after>my class IO::CatHandle is IO::Handle {
    has @!handles;
    has IO::Handle $!active-handle;

    has $.path;
    has $.chomp is rw;
    has $.nl-in;
    has str $.encoding;

    method !SET-SELF (@!handles, $!chomp, $!nl-in, $!encoding) {
        self.next-handle;
        self
    }
    method new (*@handles, :$pre-open-all,
        :$chomp = True, :$nl-in = ["\x0A", "\r\n"], :$encoding = 'utf8',
    ) {
        if $pre-open-all {
            for @handles {
                when IO::Handle {
                    next if .opened;
                    $_ = .open: :r, :$chomp, :$nl-in, :$encoding orelse .throw;
                }
                $_ = .IO.open: :r, :$chomp, :$nl-in, :$encoding orelse .throw;
            }
        }
        self.bless!SET-SELF(@handles, $chomp, $nl-in, $encoding)
    }
    method next-handle {
      # Set $!active-handle to the next handle in line, opening it if necessary
      nqp::stmts(
        nqp::if(
          nqp::defined($!active-handle),
          ($ = $!active-handle.close)), # don't sink the result, since it might
          # .. be an IO::Pipe that returns a Proc that might throw
        nqp::if(
          @!handles,
          nqp::if(
            nqp::istype(($_ := @!handles.shift), IO::Handle),
            nqp::if(
              .opened,
              ($!active-handle = $_),
              nqp::if(
                nqp::istype(
                  ($_ = .open: :r, :$!chomp, :$!nl-in, :$!encoding),
                  Failure),
                .throw,
                ($!active-handle = $_))),
            nqp::if(
              nqp::istype(($_ := .IO.open: :r, :$!chomp, :$!nl-in, :$!encoding),
                Failure),
              .throw,
              ($!active-handle = $_))),
          ($!active-handle = Nil)))
    }

    # Produce a Seq with an iterator that walks through all handles
    method comb (::?CLASS:D: |c) {}
    method split (::?CLASS:D: |c) {}
    method words (::?CLASS:D: |c) {}

    method !LINES {
      nqp::if(
        nqp::defined($!active-handle),
        (flat $!active-handle.lines, gather {
          nqp::while(
            nqp::defined(self.next-handle),
            take $!active-handle.lines)}),
        Seq.new: Rakudo::Iterator.Empty)
    }
    multi method lines(::?CLASS:D \SELF: $limit, :$close) {
        nqp::istype($limit,Whatever) || $limit == Inf
          ?? self.lines(:$close)
          !! $close
            ?? Seq.new(Rakudo::Iterator.FirstNThenSinkAll(
                self!LINES.iterator, $limit.Int, {SELF.close}))
            !! self.lines.head($limit.Int)
    }
    multi method lines(::?CLASS:D \SELF: :$close) {
      $close # use -1 as N in FirstNThenSinkAllSeq to get all items
        ?? Seq.new(Rakudo::Iterator.FirstNThenSinkAll(
            self!LINES.iterator, -1, {SELF.close}))
        !! self!LINES
    }
    multi method lines(::?CLASS:D:) { self!LINES }

    method Supply (::?CLASS:D: |c) {}

    # Get a single result, going to the next handle on EOF
    method get (::?CLASS:D: |c) {}
    method getc (::?CLASS:D: |c) {}
    method read (::?CLASS:D: |c) {}
    method readchars (::?CLASS:D: |c) {}

    # Walk through all handles, producing single result
    method slurp (::?CLASS:D: |c) {

    }
    method slurp-rest (|) {
        # We inherit deprecated .slurp-rest from IO::Handle. Pull the
        # plug on it in this class, since no one is using this yet.
        # The old IO::ArgFiles used .slurp
        die X::Obsolete.new: :old<slurp-rest>, :new<slurp>,
            :when('with IO::CatHandle')
    }
    method DESTROY {
        try .close for @!handles
    }

    method close (::?CLASS:D: --> True) {
        # Note: our IO::Handles might be IO::Pipes, whose .close
        # method returns the Proc object, which will explode when sunk if the
        # process exited unsuccessfully. So here, we ensure we never sink it.
        nqp::stmts(
          nqp::if(
            nqp::defined($!active-handle),
            $ = $!active-handle.close),
          (my int $i = -1),
          (my int $els = @!handles.elems),
          nqp::while(
            nqp::isgt_i($els, $i = nqp::add_i($i, 1)),
            nqp::if(
              nqp::istype(($_ := @!handles.AT-POS($i)), IO::Handle),
              $ = .close)))
    }
    method encoding {}
    method eof      {}
    method gist     {}
    method Str      {}
    method IO       {}
    method path     {}
    method open     {}
    method opened   {}
    method lock     {}
{'fraction_non_alphanumeric': 0.1629585798816568, 'fraction_numerical': 0.001183431952662722, 'mean_word_length': 1.7653795811518325, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 8, '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': '7555419', 'n_tokens_mistral': 2852, 'n_tokens_neox': 2780, 'n_words': 694}