### ----------------------------------------------------
### -- Sparrow6
### -- Licenses: Artistic-2.0
### -- Authors: Alexey Melezhik
### -- File: documentation/taskchecks.md
### ----------------------------------------------------
### -- Chunk 2 of 2
 within search context

Consider the same example with streams:

DSL:

    begin:

      regexp: (f) (oo)
      regexp: \S+
      regexp: \S+
      regexp: \S+
      regexp: (bar)

      code:  <<CODE
  
        for my $s (@{streams_array()}) {
            my $i=1;
            for my $l (@{$s}){
              print "layer: ", $i++, " ", (join "", map {"{$_}"} @{$l}), "\n";
            }
          print "\n";
        }
  
      CODE
  
    end:


Output:

    [task check] layer: 1 {f}{oo}
    [task check] layer: 2 {a}
    [task check] layer: 3 {b}
    [task check] layer: 4 {c}
    [task check] layer: 5 {bar}
    [task check] 
    [task check] layer: 1 {f}{oo}
    [task check] layer: 2 {1}
    [task check] layer: 3 {2}
    [task check] layer: 4 {3}
    [task check] layer: 5 {bar}
    [task check] layer: 1 {f}{oo}
    [task check] 
    [task check] layer: 1 {f}{oo}
    [task check] layer: 2 {0}
    [task check] layer: 3 {00}
    [task check] layer: 4 {000}
    [task check] layer: 5 {bar}
        
In this example `stream_array()` function returns an array of _streams_. 

Every stream is an array of _layers_, where layer is captured data for a single check step within search context logical block

Streams preserve logical block context. Number of streams relates to the number of successfully matched blocks.

Streams data presentation is much closer to what we see in original text, because it remain original text structure,
not breaking it to independent layers.

Stream could be specially useful when combined with range expressions of _different_ range lengths:

Input text:

    foo
        2
        4
        6
        8
    bar

    foo
        1
        3
    bar

    foo
        0
        0
        0
    bar


DSL code:

    between: {foo} {bar}
    
      regexp: (\d+)
    
      code:  <<CODE
    
        for my $s (@{streams_array()}) {
            my $i=1;
            for my $l (@{$s}){
              print "layer: ", $i++, " ", (join "", map {"{$_}"} @{$l}), "\n";
            }
          print "\n";
        }
    
      CODE
    
    end:
    
Output:

    [task check] stdout match (r) <(\d+)> True
    [task check] layer: 1 {2}
    [task check] layer: 2 {4}
    [task check] layer: 3 {6}
    [task check] layer: 4 {8}
    [task check] 
    [task check] layer: 1 {1}
    [task check] layer: 2 {3}
    [task check] 
    [task check] layer: 1 {0}
    [task check] layer: 2 {0}
    [task check] layer: 3 {0}

## Streams functions

Following streams functions are implemented for TC compatible languages:

* streams_array

Returns array of streams

* streams()

Hash representation of streams data. Hash keys - unique stream identeficators.

* dump_streams()

Dump streams in human readable format, useful for debugging.

# Experimental features

## Replace

Repalce allows to update file in runtime during check is performed

Following example search HELLO and digits within OK .. DONE range and then 
increment found digit and update original file: 

Input:

```
cat << HERE > $cache_root_dir/file.txt
OK
HELLO 1
DONE
HERE

cat $cache_root_dir/file.txt
```

DSL code:
```
between: {OK} {DONE}
    ~regexp: HELLO \s+ (\d+)
end:

code: <<RAKU
!raku
if matched() {
    my $ln = captures-full()[0]<index>;
    my $num = capture()[0].Int;
    $num++;
    replace("{cache_root_dir()}/file.txt",$ln,"BYE $num");
}
RAKU

code: <<BASH
!bash
cat $cache_root_dir/file.txt
BASH
```
Output:
```
[task stdout]
10:42:58 :: OK
10:42:58 :: HELLO 1
10:42:58 :: DONE
[task check]
stdout match (r) <HELLO \s+ (\d+)> True
# OK
# BYE 2
# DONE
```

Pay attention that [soft check](https://github.com/melezhik/Sparrow6/blob/master/documentation/taskchecks.md#soft-checks) is used here to let main flow continues even though if
range search fails 

# Examples

* Look at [examples](https://github.com/melezhik/Sparrow6/tree/master/examples) folder

# Environment variables

* SP6_DEBUG

Print out debug information.

* SP6_KEEP_CACHE

Don't remove cache files when checks are done. Useful when debugging.

# Author

[Aleksei Melezhik](mailto:melezhik@gmail.com)

# Home page

https://github.com/melezhik/Sparrow6

# COPYRIGHT

Copyright 2019 Alexey Melezhik.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

# See also

[Sparrow6 Development Guide](https://github.com/melezhik/Sparrow6/blob/master/documentation/development.md)

# Thanks

* To God as the One Who inspires me to do my job!





