## dist_zef-antononcube-Data-Generators.md
# Raku Data::Generators

[![Actions Status](https://github.com/antononcube/Raku-Data-Generators/actions/workflows/linux.yml/badge.svg)](https://github.com/antononcube/Raku-Data-Generators/actions)
[![Actions Status](https://github.com/antononcube/Raku-Data-Generators/actions/workflows/macos.yml/badge.svg)](https://github.com/antononcube/Raku-Data-Generators/actions)
[![Actions Status](https://github.com/antononcube/Raku-Data-Generators/actions/workflows/windows.yml/badge.svg)](https://github.com/antononcube/Raku-Data-Generators/actions)

[![](https://img.shields.io/badge/License-Artistic%202.0-0298c3.svg)](https://opensource.org/licenses/Artistic-2.0)

This Raku package has functions for generating random strings, words, pet names, vectors, arrays, and
(tabular) datasets.

### Motivation

The primary motivation for this package is to have simple, intuitively named functions
for generating random vectors (lists) and datasets of different objects.

Although, Raku has a fairly good support of random vector generation, it is assumed that commands
like the following are easier to use:

```
say random-string(6, chars => 4, ranges => [ <y n Y N>, "0".."9" ] ).raku;

```

---

## Random strings

The function `random-string` generates random strings.

Here is a random string:

```
use Data::Generators;
random-string

```

```
# rNa0FuC75aoA

```

Here we generate a vector of random strings with length 4 and characters that belong to specified ranges:

```
say random-string(6, chars => 4, ranges => [ <y n Y N>, "0".."9" ] ).raku;

```

```
# ("333N", "5N1y", "n0Y7", "7085", "6502", "y0Y7")

```

---

## Random words

The function `random-word` generates random words.

Here is a random word:

```
random-word

```

```
# psychopathy

```

Here we generate a list with 12 random words:

```
random-word(12)

```

```
# (drive-in joyless opportunistic kalian fertilize barium Malawian dingy reprobate wannabe penitential compaction)

```

Here we generate a table of random words of different types:

```
use Data::Reshapers;
my @dfWords = do for <Any Common Known Stop> -> $wt { $wt => random-word(6, type => $wt) };
say to-pretty-table(@dfWords);

```

```
# +--------+---------------+---------+-----------+----------------+-------------+--------------+
# |        |       4       |    0    |     2     |       3        |      5      |      1       |
# +--------+---------------+---------+-----------+----------------+-------------+--------------+
# | Any    | Anoectochilus |  coltan | parhelion |  heartburning  | therewithal | columniation |
# | Common |    explicit   | beastly |   cycle   | overindulgence |  extenuate  |   anaphora   |
# | Known  |   spiritism   | talaria |  feeling  |     grapy      |     guru    |    epigon    |
# | Stop   |       a       |   i've  |     0     |   shouldn't    |      X      |     few      |
# +--------+---------------+---------+-----------+----------------+-------------+--------------+

```

**Remark:** `Whatever` can be used instead of `'Any'`.

**Remark:** The function `to-pretty-table` is from the package
[Data::Reshapers](https://modules.raku.org/dist/Data::Reshapers:cpan:ANTONOV).

All word data can be retrieved with the resources object:

```
my $ra = Data::Generators::ResourceAccess.instance();
$ra.get-word-data().elems;

```

```
# 84996

```

---

## Random pet names

The function `random-pet-name` generates random pet names.

The pet names are taken from publicly available data of pet license registrations in
the years 2015–2020 in Seattle, WA, USA. See [DG1].

Here is a random pet name:

```
random-pet-name

```

```
# Murphy

```

The following command generates a list of six random pet names:

```
srand(32);
random-pet-name(6).raku

```

```
# ("Zoe", "Bandit", "Cody", "Barb", "Barack", "Cooper")

```

The named argument `species` can be used to specify specie of the random pet names.
(According to the specie-name relationships in [DG1].)

Here we generate a table of random pet names of different species:

```
my @dfPetNames = do for <Any Cat Dog Goat Pig> -> $wt { $wt => random-pet-name(6, species => $wt) };
say to-pretty-table(@dfPetNames);

```

```
# +------+----------+------------------+----------+---------+----------+---------+
# |      |    0     |        1         |    2     |    4    |    5     |    3    |
# +------+----------+------------------+----------+---------+----------+---------+
# | Any  | Hamilton | Tyson Zeus Brown | Georgia  |   Ivy   |  Mochi   |  Ellla  |
# | Cat  |   Ace    |      Felix       |   Dean   | Georgia | Little B |   Lulu  |
# | Dog  |  Louis   |      Wiley       |   Moya   |   Cleo  | Barkley  |  Buster |
# | Goat | Grayson  |     Junebug      | Winnipeg |   Lula  | Abelard  |  Grace  |
# | Pig  | Atticus  |     Atticus      |  Millie  | Atticus | Atticus  | Atticus |
# +------+----------+------------------+----------+---------+----------+---------+

```

**Remark:** `Whatever` can be used instead of `'Any'`.

The named argument (adverb) `weighted` can be used to specify random pet name choice
based on known real-life number of occurrences:

```
srand(32);
say random-pet-name(6, :weighted).raku

```

```
# ("Claire", "Ilsa", "Tinkerbelle", "Remy", "Zoe", "Bandit")

```

The weights used correspond to the counts from [DG1].

**Remark:** The implementation of `random-pet-name` is based on the Mathematica implementation
[`RandomPetName`](https://resources.wolframcloud.com/FunctionRepository/resources/RandomPetName),
[AAf1].

All pet data can be retrieved with the resources object:

```
my $ra = Data::Generators::ResourceAccess.instance();
$ra.get-pet-data()>>.elems

```

```
# {cat => 7806, dog => 12941, goat => 40, pig => 3}

```

---

## Random pretentious job titles

The function `random-pretentious-job-title` generates random pretentious job titles.

Here is a random pretentious job title:

```
random-pretentious-job-title

```

```
# Direct Functionality Director

```

The following command generates a list of six random pretentious job titles:

```
random-pretentious-job-title(6).raku

```

```
# ("Central Data Agent", "National Team Executive", "Corporate Infrastructure Associate", "Global Accountability Agent", "National Metrics Agent", "Future Mobility Planner")

```

The named argument `number-of-words` can be used to control the number of words in the generated job titles.

The named argument `language` can be used to control in which language the generated job titles are in.
At this point, only Bulgarian and English are supported.

Here we generate pretentious job titles using different languages and number of words per title:

```
my $res = random-pretentious-job-title(12, number-of-words => Whatever, language => Whatever);
say to-pretty-table($res.rotor(3));

```

```
# +---------------------------+----------------------------------+----------------------------------+
# |             0             |                1                 |                2                 |
# +---------------------------+----------------------------------+----------------------------------+
# |         Specialist        |          Администратор           |        Response Executive        |
# |   Optimization Designer   |     Супервайзор по Маркетинг     | Interactive Applications Manager |
# | Future Response Associate |         Brand Technician         |      Посредник на Качество       |
# |   Identity Administrator  | Глобален Специалист на Отчетност |       Integration Designer       |
# +---------------------------+----------------------------------+----------------------------------+

```

**Remark:** `Whatever` can be used as values for the named arguments `number-of-words` and `language`.

**Remark:** The implementation uses the job title phrases in <https://www.bullshitjob.com> .
It is, more-or-less, based on the Mathematica implementation
[`RandomPretentiousJobTitle`](https://resources.wolframcloud.com/FunctionRepository/resources/RandomPretentiousJobTitle),
[AAf2].

---

## Random reals

This module provides the function `random-real` that can be used to generate lists of real numbers
using the uniform distribution.

Here is a random real:

```
say random-real();

```

```
# 0.6148375015300324

```

Here is a random real between 0 and 20:

```
say random-real(20);

```

```
# 13.957487542046149

```

Here are six random reals between -2 and 12:

```
say random-real([-2,12], 6);

```

```
# (-1.4191627349160865 0.7985910676295189 2.5735598216113056 8.655772458122875 -0.23141703578666983 3.2473529322039427)

```

Here is a 4-by-3 array of random reals between -3 and 3:

```
say random-real([-3,3], [4,3]);

```

```
# [[-0.7777530943688706 2.633038558227515 0.9960527665422672]
#  [0.5438581449111846 0.8538444340370224 -1.2232218597405276]
#  [0.24844626265222436 1.6176949918194392 -2.9106836929578517]
#  [-1.1519301602208225 -2.168108140257122 1.575345624009456]]

```

**Remark:** The signature design follows Mathematica's function
[`RandomReal`](https://reference.wolfram.com/language/ref/RandomVariate.html).

---

## Random variates

This module provides the function `random-variate` that can be used to generate lists of real numbers
using distribution specifications.

Here are examples:

```
say random-variate(BernoulliDistribution.new(:p(0.3)), 1000).BagHash.Hash;

```

```
# {0 => 683, 1 => 317}

```

```
say random-variate(BinomialDistribution.new(:n(10), :p(0.2)), 10);

```

```
# (2 2 4 1 2 2 4 2 1 2)

```

```
say random-variate(NormalDistribution.new( µ => 10, σ => 20), 5);

```

```
# (-1.0372379191539256 15.88117685892444 2.3800289134125467 -16.077914554672056 21.434725308461598)

```

```
say random-variate(UniformDistribution.new(:min(2), :max(60)), 5);

```

```
# (33.12620384207506 54.54682825992015 44.703052532365824 18.662929703538268 16.99790622594807)

```

**Remark:** Only Normal distribution and Uniform distribution are implemented at this point.

**Remark:** The signature design follows Mathematica's function
[`RandomVariate`](https://reference.wolfram.com/language/ref/RandomVariate.html).

Here is an example of 2D array generation:

```
say random-variate(NormalDistribution.new, [3,4]);

```

```
# [[1.730441181600127 0.3420465932875971 -0.6275231817898077 0.7933012580974133]
#  [0.7546145800662779 -0.1414053357058038 0.06128413616858158 -0.48630656184266835]
#  [-0.8339285130645827 -3.0312240538258073 0.18147829328498447 1.1150963106600722]]

```

---

## Random tabular datasets

The function `random-tabular-dataset` can be used generate tabular *datasets*.

**Remark:** In this module a *dataset* is (usually) an array of arrays of pairs.
The dataset data structure resembles closely Mathematica's data structure
[`Dataset`]https://reference.wolfram.com/language/ref/Dataset.html), [WRI2].

**Remark:** The programming languages R and S have a data structure called "data frame" that
corresponds to dataset. (In the Python world the package `pandas` provides data frames.)
Data frames, though, are column-centric, not row-centric as datasets.
For example, data frames do not allow a column to have elements of heterogeneous types.

Here are basic calls:

```
random-tabular-dataset();
random-tabular-dataset(Whatever):row-names;
random-tabular-dataset(Whatever, Whatever);
random-tabular-dataset(12, 4);
random-tabular-dataset(Whatever, 4);
random-tabular-dataset(Whatever, <Col1 Col2 Col3>):!row-names;

```

Here is example of a generated tabular dataset that column names that are cat pet names:

```
my @dfRand = random-tabular-dataset(5, 3, column-names-generator => { random-pet-name($_, species => 'Cat') });
say to-pretty-table(@dfRand);

```

```
# +-----------+-----------+---------------+
# |   Tonks   |   Bailey  |    Skipper    |
# +-----------+-----------+---------------+
# | -0.425523 | 14.708426 |   extirpate   |
# | 25.249457 |  4.334753 |    humanize   |
# | 23.518357 |  9.309680 |    eccyesis   |
# |  5.089616 | 20.839470 |   prevailing  |
# | 17.328699 | 11.818831 | irreligionist |
# +-----------+-----------+---------------+

```

The display function `to-pretty-table` is from
[`Data::Reshapers`](https://modules.raku.org/dist/Data::Reshapers:cpan:ANTONOV).

**Remark:** At this point only
[*wide format*](https://en.wikipedia.org/wiki/Wide_and_narrow_data)
datasets are generated. (The long format implementation is high in my TOOD list.)

**Remark:** The signature design and implementation are based on the Mathematica implementation
[`RandomTabularDataset`](https://resources.wolframcloud.com/FunctionRepository/resources/RandomTabularDataset),
[AAf3].

---

## TODO

1. TODO Random tabular datasets generation

   * DONE Row spec
   * DONE Column spec that takes columns count and column names
   * DONE Column names generator
   * DONE Wide form implementation only
   * DONE Generators of column values
     * DONE Column-generator hash
     * DONE List of generators
     * DONE Single generator
     * DONE Turn "generators" that are lists into sampling pure functions
   * TODO Long form implementation
   * TODO Max number of values
   * TODO Min number of values
   * TODO Form (long or wide)
   * DONE Row names (automatic)
2. DONE Random reals vectors generation
3. TODO Figuring out how to handle and indicate missing values
4. TODO Random reals vectors generation according to distribution specs

   * DONE Uniform distribution
   * DONE Normal distribution
   * TODO Poisson distribution
   * TODO Skew-normal distribution
   * TODO Triangular distribution
5. DONE `RandomReal`-like implementation

   * See `random-real`.
6. DONE Selection between `roll` and `pick` for:

   * DONE `RandomWord`
   * DONE `RandomPetName`

---

## References

### Articles

[AA1] Anton Antonov,
["Pets licensing data analysis"](https://mathematicaforprediction.wordpress.com/2020/01/20/pets-licensing-data-analysis/),
(2020),
[MathematicaForPrediction at WordPress](https://mathematicaforprediction.wordpress.com).

### Functions, packages

[AAf1] Anton Antonov,
[RandomPetName](https://resources.wolframcloud.com/FunctionRepository/resources/RandomPetName),
(2021),
[Wolfram Function Repository](https://resources.wolframcloud.com/FunctionRepository).

[AAf2] Anton Antonov,
[RandomPretentiousJobTitle](https://resources.wolframcloud.com/FunctionRepository/resources/RandomPretentiousJobTitle),
(2021),
[Wolfram Function Repository](https://resources.wolframcloud.com/FunctionRepository).

[AAf3] Anton Antonov,
[RandomTabularDataset](https://resources.wolframcloud.com/FunctionRepository/resources/RandomTabularDataset),
(2021),
[Wolfram Function Repository](https://resources.wolframcloud.com/FunctionRepository).

[SHf1] Sander Huisman,
[RandomString](https://resources.wolframcloud.com/FunctionRepository/resources/RandomString),
(2021),
[Wolfram Function Repository](https://resources.wolframcloud.com/FunctionRepository).

[WRI1] Wolfram Research (2010),
[RandomVariate](https://reference.wolfram.com/language/ref/RandomVariate.html),
Wolfram Language function.

[WRI2] Wolfram Research (2014),
[Dataset](https://reference.wolfram.com/language/ref/Dataset.html),
Wolfram Language function.

### Data repositories

[DG1] Data.Gov,
[Seattle Pet Licenses](https://catalog.data.gov/dataset/seattle-pet-licenses),
[catalog.data.gov](https://catalog.data.gov).


## dist_zef-Air4x-Chart-EasyGnuplot.md
# Chart::EasyGnuplot

A simple modules to make simple plots, without having to think about
Gnuplot internals.

# Example

Let's plot the fuction "sin(x)-x\*cos(x)"

```
use v6.d;
use Chart::EasyGnuplot;

my @x = 0.0 .. (2*π);
my @y = gather {
	for @x -> $x{
		take (sin($x)-$x*cos(x));
	}
}

line-plot("sin(x)-x*cos(x)", @x, @y, "Example.png");

```

![plotted func](Example.png)


## note.md
note

Combined from primary sources listed below.

# [In Independent routines](#___top "go to top of document")[§](#(Independent_routines)_routine_note "direct link")

See primary documentation
[in context](/type/independent-routines#routine_note)
for **routine note**.

```raku
method note(Mu: -->Bool:D)
multi  note(            --> Bool:D)
multi  note(Str:D $note --> Bool:D)
multi  note(**@args     --> Bool:D)
```

Like [`say`](/routine/say) (in the sense it will invoke the `.gist` method of the printed object), except it prints output to [`$*ERR`](/language/variables#index-entry-%24%2AERR) handle (`STDERR`). If no arguments are given to subroutine forms, will use string `"Noted"`.

```raku
note;       # STDERR OUTPUT: «Noted␤»
note 'foo'; # STDERR OUTPUT: «foo␤»
note 1..*;  # STDERR OUTPUT: «1..Inf␤»

```

This command will also autothread on [`Junction`](/type/Junction)s, and is guaranteed to call `gist` on the object if it's a subclass of [`Str`](/type/Str).


## dist_zef-antononcube-Graph.md
# Graph

[![Actions Status](https://github.com/antononcube/Raku-Graph/actions/workflows/linux.yml/badge.svg)](https://github.com/antononcube/Raku-Graph/actions)
[![Actions Status](https://github.com/antononcube/Raku-Graph/actions/workflows/macos.yml/badge.svg)](https://github.com/antononcube/Raku-Graph/actions)
[![Actions Status](https://github.com/antononcube/Raku-Graph/actions/workflows/windows.yml/badge.svg)](https://github.com/antononcube/Raku-Graph/actions)

[![](https://raku.land/zef:antononcube/Graph/badges/version)](https://raku.land/zef:antononcube/Graph)
[![](https://img.shields.io/badge/License-Artistic%202.0-0298c3.svg)](https://opensource.org/licenses/Artistic-2.0)

Raku package for (discrete mathematics) graph data structures and algorithms.

For a quick introduction see the video ["Graph demo in Raku (teaser)"](https://www.youtube.com/watch?v=0uJl9q7jIf8), [AAv1], (5 min.)

**Remark:** This package is *not* for drawing and rendering images.
It is for the abstract data structure [***graph***](https://en.wikipedia.org/wiki/Graph_(discrete_mathematics)).

---

## Installation

From Zef ecosystem:

```
zef install Graph

```

From GitHub:

```
zef install https://github.com/antononcube/Raku-Graph.git

```

---

## Design and implementation details

### Motivation

* Needless to say, Graph theory is huge.
  * But certain algorithms like path and cycle finding are relatively easy to implement
    and are fundamental both mathematics-wise and computer-science-wise.
* Having fast shortest path finding algorithms in graphs should be quite a booster for geography related projects.

### Design

* The central entity is the `Graph` class.
* `Graph` is as generic as possible.
  * Meaning it is for directed graphs.
  * Undirected graphs are represented as directed graphs.
    * I.e. with twice as many edges than necessary.
  * The current graph representation is with hash-of-hashes, (`adjacency-list`), that keeps from-to-weight relationships.
    * For example, `$g.adjacency-list<1><2>` gives the weight of the edge connecting vertex "1" to vertex "2".
  * The vertexes are only strings.
    * Not a "hard" design decision.
    * More general vertexes can be imitated (in the future) with vertex tags.
      * This is related to having (in Raku) sparse matrices with named rows and columns.
* Since I know Mathematica / Wolfram Language (WL) very well, many of the method names and signatures are
  strongly influenced by the corresponding functions in WL.
  * I do not follow them too strictly, though.
  * One reason is that with Raku it is much easier to have and use named arguments than with WL.

### Implementation

* I was considering re-programming Perl5’s "Graph", [JHp1], into Raku, but it turned out it was easier to write the algorithms directly in Raku.
  * (To me at least...)
* The classes creating special graphs, like, grid-graph, star-graph, etc., are sub-classes of `Graph`
  with files in the sub-directory "Graph".
  * See usage of such classes [here](./examples/Named-graphs.raku).

### Visualization

* Visualizing the graphs (the objects of the class `Graph`) is very important.
  * Has to be done from the very beginning of the development.
    * (Again, for me at least...)
* The class `Graph` has the methods `dot`, `graphml`, `mermaid`, and `wl` for representing the graphs for
  GraphViz, GraphML, Mermaid-JS, and Wolfram Language (WL) respectively.
* Mermaid's graph nodes and edges arrangement algorithm can produce "unexpected" images for the standard, parameterized graphs.
  * Like, "grid graph", "cycle graph", etc.

### Performance

* So far, I have tested the path finding algorithms on "Graph" on small graphs and moderate size graphs.
  * The largest random graph I used had 1000 vertexes and 1000 edges.
  * Mathematica (aka Wolfram Language) can be 500 ÷ 10,000 faster.
  * I hope good heuristic functions for the "A\* search" method would make `find-shortest-path` fast enough,
    for say country / continent route systems.
    * With the larger, 1,000-vertex random graphs finding paths with the method "a-star" is ≈50 faster than with the method "dijkstra".
      * See [here](./examples/Performance.raku).
* Setting up comprehensive performance profiling and correctness testing is somewhat involved.
  * One main impediment is that in Raku one cannot expect and specify same random numbers between different sessions.

---

## Usage examples

Here we create a dataset of edges:

```
my @edges =
        { from => '1', to => '5', weight => 1 },
        { from => '1', to => '7', weight => 1 },
        { from => '2', to => '3', weight => 1 },
        { from => '2', to => '4', weight => 1 },
        { from => '2', to => '6', weight => 1 },
        { from => '2', to => '7', weight => 1 },
        { from => '2', to => '8', weight => 1 },
        { from => '2', to => '10', weight => 1 },
        { from => '2', to => '12', weight => 1 },
        { from => '3', to => '4', weight => 1 },
        { from => '3', to => '8', weight => 1 },
        { from => '4', to => '9', weight => 1 },
        { from => '5', to => '12', weight => 1 },
        { from => '6', to => '7', weight => 1 },
        { from => '9', to => '10', weight => 1 },
        { from => '11', to => '12', weight => 1 };

@edges.elems;

```

```
# 16

```

**Remark:** If there is no `weight` key in the edge records the weight of the edge is taken to be 1.

Here we create a graph object with the edges dataset:

```
use Graph;

my $graph = Graph.new;
$graph.add-edges(@edges);

```

```
# Graph(vertexes => 12, edges => 16, directed => False)

```

Here are basic properties of the graph:

```
say 'edge count   : ', $graph.edge-count;
say 'vertex count : ', $graph.vertex-count;
say 'vertex list  : ', $graph.vertex-list;

```

```
# edge count   : 16
# vertex count : 12
# vertex list  : (1 10 11 12 2 3 4 5 6 7 8 9)

```

Here we display the graph using [Mermaid-JS](https://mermaid.js.org), (see also, [AAp1]):

```
$graph.mermaid(d=>'TD')

```

```
graph TD
10 --- 2
10 --- 9
2 --- 3
3 --- 4
3 --- 8
2 --- 4
2 --- 7
12 --- 2
2 --- 8
2 --- 6
1 --- 5
1 --- 7
6 --- 7
12 --- 5
11 --- 12
4 --- 9

```

Here we find the shortest path between nodes "1" and "4":

```
say 'find-shortest-path : ', $graph.find-shortest-path('1', '4');

```

```
# find-shortest-path : [1 7 2 4]

```

Here we find all paths between "1" and "4", (and sort them by length and vertex names):

```
say 'find-path : ' , $graph.find-path('1', '4', count => Inf).sort({ $_.elems ~ ' ' ~ $_.join(' ') });

```

```
# find-path : ([1 7 2 4] [1 5 12 2 4] [1 7 2 3 4] [1 7 6 2 4] [1 5 12 2 3 4] [1 7 2 10 9 4] [1 7 2 8 3 4] [1 7 6 2 3 4] [1 5 12 2 10 9 4] [1 5 12 2 8 3 4] [1 7 6 2 10 9 4] [1 7 6 2 8 3 4])

```

Here we find a [Hamiltonian path](https://en.wikipedia.org/wiki/Hamiltonian_path) in the graph:

```
say 'find-hamiltonian-path : ' , $graph.find-hamiltonian-path();

```

```
# find-hamiltonian-path : [10 9 4 3 8 2 6 7 1 5 12 11]

```

Here we find a cycle:

```
say 'find-cycle : ' , $graph.find-cycle().sort({ $_.elems ~ ' ' ~ $_.join(' ') });

```

```
# find-cycle : ([2 3 4 2])

```

Here we find all cycles in the graph:

```
say 'find-cycle (all): ' , $graph.find-cycle(count => Inf).sort({ $_.elems ~ ' ' ~ $_.join(' ') });

```

```
# find-cycle (all): ([2 3 4 2] [2 3 8 2] [2 6 7 2] [10 2 4 9 10] [2 4 3 8 2] [1 5 12 2 7 1] [10 2 3 4 9 10] [1 5 12 2 6 7 1] [10 2 8 3 4 9 10])

```

---

## Graph plotting

### Graph formats

The class `Graph` has the following methods of graph visualization:

* `wl` for making [Wolfram Language graphs](https://reference.wolfram.com/language/ref/Graph.html)
* `dot` for visualizing via [Graphviz](https://graphviz.org) using the [DOT language](https://graphviz.org/doc/info/lang.html)
* `graphml` for [GraphML](http://graphml.graphdrawing.org) visualizations
* `mermaid` for [Mermaid-JS](https://mermaid.js.org) visualizations

### Visualizing via DOT format

In Jupyter notebooks with a Raku kernel graph visualization can be done with the method `dot` and its adverb ":svg".

First, [install Graphviz](https://graphviz.org/download/).

On macOS the installation can be done with:

```
brew install graphviz

```

Here a wheel graph is made and its DOT format is converted into SVG format (rendered automatically in Jupyter notebooks):

```
use Graph::Wheel;
Graph::Wheel.new(12).dot(:svg)

```

For more details see notebook ["DOT-visualizations.ipynb"](./docs/DOT-visualizations.ipynb).

### Visualizing via D3.js

In Jupyter notebooks with a Raku kernel graph visualization can be done with the function `js-d3-graph-plot`
of the package ["JavaScript::D3"](https://github.com/antononcube/Raku-JavaScript-D3).

The visualizations with "JavaScript::D3" are very capricious. Currently they:

* Do not work with [JupyterLab](https://jupyter.org), but only with the "classical" Jupyter notebook.
* Work nicely with the Jupyter notebook plugin(s) of Visual Studio Code, but often require re-loading of the notebooks.

The points above were the main reasons to develop the DOT format visualization.
Most of the documentation notebooks show the graphs using both "JavaScript::D3" and DOT-SVG.

---

## TODO

### Main, core features

* TODO Object methods
  * DONE Str and gist methods
  * DONE Deep copy
  * DONE Creation from another graph.
  * TODO Ingest vertexes and edges of another `Graph` object
  * TODO Comparison: `eqv` and `ne`.
* DONE Disjoint graphs
  * The graphs can be disjoint as long as the components have edges.
  * Related, the class `Graph` does supports "lone vertices."
    * They have empty adjacency values.
* TODO Vertexes
  * DONE Vertex list
  * DONE Vertex count
  * DONE Vertex degree
  * DONE in-degree, edges-at
  * DONE out-degree, edges-from
  * DONE Delete vertex(es)
  * DONE Add vertex
  * DONE Has vertex
  * TODO Vertex tags support
* TODO Edges
  * DONE Edge list
  * DONE Edge dataset
  * DONE Edge count
  * DONE Add edge
  * DONE Delete edge(s)
  * DONE Has edge
  * TODO Edge tags support
* TODO Matrix representation
  * Sparse matrices are needed before "seriously" considering this.
  * Sparse matrices should be easy to create using the (already implemented) edge dataset.
  * DONE Adjacency matrix (dense)
  * TODO Adjacency matrix (sparse)
  * Incidence matrix (dense)
  * Incidence matrix (sparse)

### Graph programming

* Depth first scan / traversal
  * Scan a graph in a depth-first order.
  * This is already implemented, it has to be properly refactored.
    * See Depth-First Search (DFS) named (private) methods.
* Breadth first scan / traversal
  * Scan a graph in a breadth-first order.

### Paths, cycles, flows

* DONE Shortest paths
  * DONE Find shortest path
  * DONE Find Hamiltonian paths
    * For both the whole graph or for a given pair of vertexes.
    * Algorithms:
      * Backtracking, `method => 'backtracking'`)
      * Application Warnsdorf's rule for backtracking, `:warnsdorf-rule`
      * Angluin-Valiant (probabilistic), `method => 'random'`
* TODO Flows
  * TODO Find maximum flow
  * TODO Find minimum cost flow
* TODO Distances
  * DONE Graph distance
    * See shortest path.
  * TODO Graph distance matrix
    * Again, requires choosing a matrix Raku class or package.
* DONE Longest shortest paths
  * DONE Vertex eccentricity
  * DONE Graph radius
  * DONE Graph diameter
  * DONE Graph center
  * DONE Graph periphery
* DONE Weakly connected component
* DONE Strongly connected component
  * DONE [Tarjan's algorithm](https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm)
  * TODO [Kosaraju's algorithm](https://en.wikipedia.org/wiki/Kosaraju%27s_algorithm)
* DONE Topological sort
  * Using Tarjan's algorithm
* TODO Cycles and tours
  * DONE Find cycle
    * Just one cycle
    * All cycles
  * TODO Find shortest tour
  * TODO Find postman tour
    * DONE Eulerian and semi-Eulerian graphs
    * TODO General graphs
  * TODO Find Eulerian cycle
  * TODO Find Hamiltonian cycle
  * TODO Find cycle matrix
* TODO Independent paths
  * DONE Find paths
  * TODO Find edge independent paths
  * TODO Find edge vertex paths

### Matching, coloring

* DONE Check is a graph bipartite
* DONE [Hungarian algorithm for bipartite graphs](https://en.wikipedia.org/wiki/Hungarian_algorithm)
  * At [tum.de](https://algorithms.discrete.ma.tum.de/graph-algorithms/matchings-hungarian-method/index_en.html)
* TODO Perfect match for bipartite graphs
* TODO Matching edges

### Operations

* TODO Unary graph operations
  * DONE Reversed graph
  * DONE Complement graph
  * DONE Subgraph
    * For given vertices and/or edges.
  * DONE Neighborhood graph
    * For given vertices and/or edges.
  * DONE Make undirected
    * Can be implemented as `Graph.new($g, :!directed)`.
    * But maybe it is more efficient to directly manipulate `adjacency-list`.
  * DONE Make directed
    * It is not just a flag change of `$!directed`.
    * Implement the methods: `Whatever`, "Acyclic", "Random".
  * TODO Edge contraction
  * TODO Vertex contraction
  * TODO Line graph
  * TODO Dual graph
* TODO Binary graph operations
  * DONE Union of graphs
  * DONE Intersection of graphs
  * DONE Difference of graphs
  * DONE Disjoint union of graphs
  * TODO Product of graphs (AKA "box product")
    * TODO Cartesian
    * TODO Co-normal
    * TODO Lexicographic
    * TODO Normal
    * TODO Rooted
    * TODO Strong
    * TODO Tensor

### Construction

* DONE Construction of parameterized graphs
  * DONE [Complete graphs](https://en.wikipedia.org/wiki/Complete_graph)
  * DONE [Cycle graphs](https://en.wikipedia.org/wiki/Cycle_graph)
  * DONE [Hypercube graphs](https://en.wikipedia.org/wiki/Hypercube_graph)
  * DONE [Grid graphs](https://en.wikipedia.org/wiki/Lattice_graph)
  * DONE [Knight tour graphs](https://en.wikipedia.org/wiki/Knight%27s_graph)
  * DONE [Star graphs](https://en.wikipedia.org/wiki/Star_graph)
  * DONE Path graphs
  * DONE [Wheel graphs](https://en.wikipedia.org/wiki/Wheel_graph)
  * DONE Indexed graphs
  * DONE [Hexagonal grid graphs](https://mathworld.wolfram.com/HexagonalGridGraph.html)
* DONE Construction of random graphs
  * Since different kinds of vertex-edge distributions exists, separate distributions objects are used.
    * See `Graph::Distribution`.
  * DONE [Barabasi-Albert distribution](https://en.wikipedia.org/wiki/Barab%C3%A1si%E2%80%93Albert_model)
  * DONE Bernoulli distribution
  * DONE [de Solla Price's model distribution](https://en.wikipedia.org/wiki/Price%27s_model)
  * DONE "Simple" random `(m, n)` graphs with m-vertexes and n-edges between them
    * This was the first version of `Graph::Random`.
    * Refactored to be done via the uniform graph distribution.
  * DONE [Watts–Strogatz model distribution](https://en.wikipedia.org/wiki/Watts%E2%80%93Strogatz_model)
  * DONE Uniform distribution
* TODO Construction of *individual* graphs
  * TODO Bull graph
  * TODO Butterfly graph
  * TODO Chavatal graph
  * TODO Diamond graph
  * TODO Durer graph
  * TODO Franklin graph
  * DONE [Petersen graph](https://en.wikipedia.org/wiki/Petersen_graph)
  * TODO Wagner graph
* Creation from
  * Adjacency matrix (dense)
  * Adjacency matrix (sparse)
  * Incidence matrix (dense)
  * Incidence matrix (sparse)

### Tests

* TODO Unit tests
  * DONE Sanity
  * DONE Undirected graphs
  * DONE Vertex removal
  * DONE Edge removal
  * DONE Bipartite graph check
  * TODO Directed graphs cycles
* TODO Cross-verification with Mathematica
  * DONE General workflow programming/setup
  * TODO Path finding
  * TODO Cycle finding

### Documentation

* DONE Basic usage over undirected graphs
* TODO Basic usage over directed graphs
* DONE Regular graphs creation (Grid, Wheel, etc.)
  * [Notebook with a gallery of graphs](./docs/Named-graphs-gallery.ipynb)
* DONE Random graphs creation
* DONE DOT language visualizations

---

## References

### Articles

[Wk1] Wikipedia entry, ["Graph (discrete mathematics)"](https://en.wikipedia.org/wiki/Graph_(discrete_mathematics)).

[Wk2] Wikipedia entry, ["Graph theory"](https://en.wikipedia.org/wiki/Graph_theory).

[Wk3] Wikipedia entry, ["Glossary of graph theory"](https://en.wikipedia.org/wiki/Glossary_of_graph_theory).

[Wk4] Wikipedia entry, ["List of graphs"](https://en.wikipedia.org/wiki/List_of_graphs) (aka "Gallery of named graphs.")

[Wk5] Wikipedia entry, ["Hamiltonian path"](https://en.wikipedia.org/wiki/Hamiltonian_path).

### Packages

[AAp1] Anton Antonov,
[WWW::MermaidInk Raku package](https://github.com/antononcube/Raku-WWW-MermaidInk),
(2023),
[GitHub/antononcube](https://github.com/antononcube).

[AAp2] Anton Antonov,
[Proc::ZMQed Raku package](https://github.com/antononcube/Raku-Proc-ZMQed),
(2022),
[GitHub/antononcube](https://github.com/antononcube).

[AAp3] Anton Antonov,
[JavaScript:3 Raku package](https://github.com/antononcube/Raku-JavaScript-D3),
(2022-2024),
[GitHub/antononcube](https://github.com/antononcube).

[JHp1] Jarkko Hietaniemi,
[Graph Perl package](https://metacpan.org/dist/Graph/view/lib/Graph.pod),
(1998-2014),
[MetaCPAN](https://metacpan.org).

### Videos

[AAv1] Anton Antonov,
["Graph demo in Raku (teaser)"](https://www.youtube.com/watch?v=0uJl9q7jIf8),
(2024),
[YouTube/@AAA4Prediction](https://www.youtube.com/@AAA4Prediction).

[AAv2] Anton Antonov,
["Graph neat examples in Raku (Set 1)"](https://www.youtube.com/watch?v=5qXgqqRZHow),
(2024),
[YouTube/@AAA4Prediction](https://www.youtube.com/@AAA4Prediction).

[AAv3] Anton Antonov,
["Sparse matrix neat examples in Raku"](https://www.youtube.com/watch?v=kQo3wpiUu6w),
(2024),
[YouTube/@AAA4Prediction](https://www.youtube.com/@AAA4Prediction).


## dist_zef-p6steve-CLI-Wordpress.md
[![](https://img.shields.io/badge/License-Artistic%202.0-0298c3.svg)](https://opensource.org/licenses/Artistic-2.0)

# Raku CLI::Wordpress

This module provides a simple abstraction to the Wordpress command line interface (wpcli) for site launch and maintenance.

If you encounter a feature you want that's not implemented by this module (and there are many), please consider sending a pull request.

## Prerequisites

* ubuntu server with docker, docker-compose, raku and zef (e.g. by using [raws-ec2](https://github.com/p6steve/raku-CLI-AWS-EC2-Simple))
* located at a static IP address (e.g. `raws-ec2 --eip launch`) with ssh access (e.g. via `raws-ec2 connect`)
* domain name DNS set with A records @ and www to the target's IP address

## Getting Started

* ssh in and install CLI::Wordpress on server to get the rawp command `zef install https://github.com/p6steve/raku-CLI-Wordpress.git` *[or CLI::Wordpress]*
* edit `vi ~/.rawp-config/wordpress-launch.yaml` with your domain name and wordpress configuration
* launch a new instance of Wordpress & setup ssl certificate `rawp setup && rawp launch`
* view your new Wordpress site frontend at <https://yourdomain.com> and configure basics
* setup ssl cert renewals via letsencrypt `rawp renewal`

## wordpress-launch.yaml

```
        instance:
            domain-name: your_domain
            admin-email: 'adminyour_domain'
            db-image: mysql:8.0
            wordpress-image: wordpress:php8.0-fpm-alpine
            webserver-image: nginx:1.15.12-alpine
            certbot-image: certbot/certbot
            wpcli-image: wordpress:cli-php8.0

```

## WP CLI Examples

`rawp wp '--info'`

```
OS:	Linux 5.15.0-1031-aws #35-Ubuntu SMP Fri Feb 10 02:07:18 UTC 2023 x86_64
Shell:
PHP binary:	/usr/local/bin/php
PHP version:	8.0.28
php.ini used:
MySQL binary:	/usr/bin/mysql
MySQL version:	mysql  Ver 15.1 Distrib 10.6.12-MariaDB, for Linux (x86_64) using readline 5.1
SQL modes:
WP-CLI root dir:	phar://wp-cli.phar/vendor/wp-cli/wp-cli
WP-CLI vendor dir:	phar://wp-cli.phar/vendor
WP_CLI phar path:	/var/www/html
WP-CLI packages dir:
WP-CLI cache dir:	/.wp-cli/cache
WP-CLI global config:
WP-CLI project config:
WP-CLI version:	2.7.1

```

`rawp wp 'search-replace "test" "experiment" --dry-run'`

```
Table	Column	Replacements	Type
wp_commentmeta	meta_key	0	SQL
wp_commentmeta	meta_value	0	SQL
wp_comments	comment_author	0	SQL
...
wp_links	link_rss	0	SQL
wp_options	option_name	0	SQL
wp_options	option_value	3	PHP
wp_options	autoload	0	SQL
...
wp_users	display_name	0	SQL
Success: 3 replacements to be made.

```

## CMDs

* setup # position all config files for docker-compose and render wordpress-launch.yaml info
* launch # docker-compose up staging server, if OK then get ssl and restart
* renewal # configure crontab for ssl cert renewal
* up # docker-compose up -d
* wp 'cmd' # run wpcli command - viz. <https://developer.wordpress.org/cli/commands/>
* down # docker-compose down
* ps # docker-compose ps
* connect # docker exec to wordpress server
* terminate # rm volumes & reset

## Usage

```
  rawp <cmd> [<wp>]

    <cmd>     One of <setup launch renewal up wp down ps connect terminate>
    [<wp>]    A valid wp cli cmd (viz. https://developer.wordpress.org/cli/commands/)

```

### Copyright

copyright(c) 2023 Henley Cloud Consulting Ltd.


## dist_zef-bduggan-Pod-To-Raku.md
[![Actions Status](https://github.com/bduggan/raku-pod-to-raku/actions/workflows/linux.yml/badge.svg)](https://github.com/bduggan/raku-pod-to-raku/actions/workflows/linux.yml)
[![Actions Status](https://github.com/bduggan/raku-pod-to-raku/actions/workflows/macos.yml/badge.svg)](https://github.com/bduggan/raku-pod-to-raku/actions/workflows/macos.yml)

# NAME

Pod::To::Raku -- Extract Pod into standalone Raku

# SYNOPSIS

```
raku --doc=Raku in.raku > out.raku
raku --doc=Raku in.rakumod > out.raku
raku --doc=Raku::Plus in.pod > out.raku

```

# DESCRIPTION

This is a simple way of extracting pod from a file and serializing it using the `.raku` method.

This can be helpful to separate the pod from a raku module or program in which it is embedded. It is designed to be used along with the command line option `--doc` for the raku executable, as shown above.

# EXAMPLE

Given a file like this named `add.raku` with some declarator pod:

```
#| add two numbers
sub add($a, $b) {
    $a + $b;
}

```

Run

```
raku --doc=Raku add.raku

```

to get

```
$[
  Pod::Block::Declarator.new(
      WHEREFORE => sub add ($a, $b) { #`(Sub|3053844670056) ... },
      leading => [["add two numbers"],],
      trailing => [],
      config => {}, contents => []
  )
]

```

# BONUS FEATURES

Also included: `Pod::To::Raku::Plus` and `find-raku-module`.

Use `Raku::Plus` to add the file and line to `WHEREFORE`:

```
raku --doc=Raku::Plus add.raku

```

which yields

```
$[
  Pod::Block::Declarator.new(
      WHEREFORE => {
          :file("add.raku"),
          :line(2),
          :name("add"),
          :sig(:($a, $b))
     },
     leading => [["add two numbers"],], trailing => [], config => {}, contents => [])
  ]

```

Use `find-raku-module` to get some metadata (including filenames) for a module:

```
find-raku-module JSON::Fast

```

yields

```
{
    "repo-id": "inst",
    "provides": [
	    {
		    "lib/JSON/Fast.pm6": {
			    "file": "F13CDD097310A0775131666979B65ADF692574DD",
			    "time": null
		    },
		    "file": "...moar-2024.12/share/perl6/site/sources/F13CDD097310A0775131666979B65ADF692574DD"
	    }
    ],
    "meta": {
	    "ver": "0.19",
	    "source": "F13CDD097310A0775131666979B65ADF692574DD",
	    "auth": "cpan:TIMOTIMO",
	    "api": "0",
	    "checksum": "A498E97EDAC5D22E53386172C9A3EA5670411BCD"
    },
    "JSON::Fast": {
	    "lib/JSON/Fast.pm6": "...moar-2024.12/share/perl6/site/sources/F13CDD097310A0775131666979B65ADF692574DD"
    },
    "description": "A naive, fast json parser and serializer; drop-in replacement for JSON::Tiny"
}

```

# SEE ALSO

`Pod::Load`


## return.md
return

Combined from primary sources listed below.

# [In Control flow](#___top "go to top of document")[§](#(Control_flow)_return_return "direct link")

See primary documentation
[in context](/language/control#return)
for **return**.

The sub `return` will stop execution of a subroutine or method, run all relevant [phasers](/language/phasers#Block_phasers) and provide the given return value to the caller. The default return value is [`Nil`](/type/Nil). If a return [type constraint](/language/signatures#Constraining_return_types) is provided it will be checked unless the return value is [`Nil`](/type/Nil). If the type check fails the exception [`X::TypeCheck::Return`](/type/X/TypeCheck/Return) is thrown. If it passes a control exception is raised and can be caught with [CONTROL](/language/phasers#CONTROL).

Any `return` in a block is tied to the first [`Routine`](/type/Routine) in the outer lexical scope of that block, no matter how deeply nested. Please note that a `return` in the root of a package will fail at runtime. A `return` in a block that is evaluated lazily (e.g. inside `map`) may find the outer lexical routine gone by the time the block is executed. In almost any case `last` is the better alternative. Please check [the functions documentation](/language/functions#Return_values) for more information on how return values are handled and produced.


## wraphandle.md
class Routine::WrapHandle

Holds all information needed to unwrap a wrapped routine.

class WrapHandle { ... }

`WrapHandle` is a *Rakudo private class* created and returned by [wrap](/type/Routine#method_wrap). Its only use is to unwrap wrapped routines. Either call [unwrap](/type/Routine#method_unwrap) on a routine object or call the method `restore` on a `Routine::WrapHandle` object.

```raku
sub f() { say 'f was called' }
my $wrap-handle = &f.wrap({ say 'before'; callsame; say 'after' });
f;                    # OUTPUT: «before␤f was called␤after␤»
$wrap-handle.restore;
f;                    # OUTPUT: «f was called␤»
```

As such private class, it may suffer any kind of changes without prior notice. It is only mentioned here since it is visible by the user who checks the return type of the `Routine.wrap` method.

# [Methods](#class_Routine::WrapHandle "go to top of document")[§](#Methods "direct link")

## [method restore](#class_Routine::WrapHandle "go to top of document")[§](#method_restore "direct link")

```raku
method restore(--> Bool:D)
```

Unwraps a wrapped routine and returns `Bool::True` on success.


## dist_zef-lizmat-CodeUnit.md
[![Actions Status](https://github.com/lizmat/CodeUnit/actions/workflows/linux.yml/badge.svg)](https://github.com/lizmat/CodeUnit/actions) [![Actions Status](https://github.com/lizmat/CodeUnit/actions/workflows/macos.yml/badge.svg)](https://github.com/lizmat/CodeUnit/actions) [![Actions Status](https://github.com/lizmat/CodeUnit/actions/workflows/windows.yml/badge.svg)](https://github.com/lizmat/CodeUnit/actions)

# NAME

CodeUnit - provide a unit for execution of code

# SYNOPSIS

```
use CodeUnit;

my $cu = CodeUnit.new;
$cu.eval('my $a = 42');
$cu.eval('say $a');  # 42

$cu.eval('say $b');
with $cu.exception {
    note .message.chomp;  # Variable '$b' is not declared...
    $cu.exception = Nil;
}

```

# DESCRIPTION

The `CodeUnit` distribution provides an interface to a compiler context that allows code to be evaluated by given strings, while maintaining context between states.

As such it provides one of the underlying functionalities of a REPL (Read Evaluate Print Loop), but could be used by itself for a multitude of uses.

# METHODS

## new

```
my $cu1 = CodeUnit.new;

my $context = context;
my $cu2 = CodeUnit.new(:$context);

# start with grammar including any mixins
my $cu3 = CodeUnit.new(:lang(BEGIN $*LANG));

```

The `new` method instantiates a `CodeUnit` object. It takes the following named arguments:

### :context

Optional. The `:context` named argument can be specified with a value returned by the `context` subroutine. If not specified, will assume a fresh context without any outer / caller lexicals visible.

Used value available with the `.context` method.

### :compiler

Optional. The `:compiler` named argument can be specified to indicate the low level compiler object that sould be used. Can be specified as a string, in which case it will be used as an argument to the `nqp::getcomp` function to obtain the low level compiler object. Defaults to `"Raku"`.

Used value available with the `.compiler` method.

### :multi-line-ok

Optional, Boolean. Indicate whether it is ok to interprete multiple lines of input as a single statement to evaluate. Defaults to `True` unless the `RAKUDO_DISABLE_MULTILINE` environment variable has been specified with a true value.

Used value available with the `.multi-line-ok` method, and can be used as a left-value to change.

### :grammar

Optional. Specifies the `grammar` to be used initially. Defaults to the standard Raku grammar, or to what has been specified with `:lang`.

Value available with the `.grammar` method.

### :actions

Optional. Specifies the action class to be used. Defaults to the standard Raku actions, or to what the `.actions` method returns on what is specified with `:lang`.

### :lang

Optional. Specified which `grammar` / action class to be used. Defaults to the standard Raku `grammar` and action class. If specified, this is usually `BEGIN $*LANG`;

## eval

```
$cu.eval('my $a = 42');
$cu.eval('say $a');  # 42

```

The `eval` method evaluates the given string with Raku code within the context of the code unit, and returns the result of the evaluation.

## reset

```
$cu.reset;

```

The `reset` method resets the context of the code unit to its initial state as (implicitely) specified with `.new`.

## compiler-version

```
say $cu.compiler-version;
# Welcome to Rakudo™ v2025.01.
# Implementing the Raku® Programming Language v6.d.
# Built on MoarVM version 2025.01.

```

The `compiler-version` method returns the compiler version information, which is typically shown when starting a REPL.

## context-completions

```
.say for $cu.context-completions;

```

The `context-completions` method returns an unsorted list of context completion candidates found in the context of the code unit, which are typically used to provide completions in a REPL (hence the name).

## state

The `state` method returns one of the `Status` enums to indicate the result of the last call to `.eval`. It can also be used as a left-value to set the state (usually to `OK`).

## exception

```
with $cu.exception {
    note .message.chomp;  # Variable '$b' is not declared...
    $cu.exception = Nil;
}

```

The `exception` method returns the `Exception` object if anything went wrong in the `.eval` call. Note that this can also be the case even if the state is `OK`. Can also be used as a left-value to (re)set.

# ENUMS

## Status

The `Status` enum is exported: it is used by the `state` method to indicate the state of the last call to `.eval`. It provides the following states:

* OK (0) - evalution ok
* MORE-INPUT (1) - string looks like incomplete code
* CONTROL (2) - some kind of control statement was executed

# SUBROUTINES

## context

```
my $context = context;
my $cu = CodeUnit.new(:$context);

```

The `context` subroutine returns a context object that can be used to initialize the context of a code unit with.

# CAVEATS

## "Invisible" variables

By default, Raku does a lot of compile-time as well as run-time optimizations. This may lead to lexical variables being optimized away, and thus become "invisible" to introspection. If that appears to be the case, then starting Raku with `--optimize=off` may make these "invisble" variables visible.

## Each call is a scope

Because each call introduces its own scope, certain side-effects of this scoping behaviour may produce unexpected results and/or errors. For example: `my $a = 42`, followed by `say $a`, is really:

```
my $a = 42;
{
    say $a;
}

```

This works because the lexical variable `$a` is visible from the scope that has the `say`.

Another example which you might expect to give at least a warning, but doesn't: `my $a = 42;` followed by `my $a = 666`, which would normally produce a worry: "Redeclaration of symbol '$a'", but doesn't here because they are different scopes:

```
my $a = 42;
{
    my $a = 666;
}

```

As you can see, the second `$a` shadows the first `$a`, and is not a worry as such.

Future versions of `CodeUnit` may be able to work around this scoping behaviour.

# AUTHOR

Elizabeth Mattijsen [liz@raku.rocks](mailto:liz@raku.rocks)

Source can be located at: <https://github.com/lizmat/CodeUnit> . Comments and Pull Requests are welcome.

If you like this module, or what I'm doing more generally, committing to a [small sponsorship](https://github.com/sponsors/lizmat/) would mean a great deal to me!

# COPYRIGHT AND LICENSE

Copyright 2025 Elizabeth Mattijsen

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.


## eqv.md
eqv

Combined from primary sources listed below.

# [In Match](#___top "go to top of document")[§](#(Match)_infix_eqv "direct link")

See primary documentation
[in context](/type/Match#infix_eqv)
for **infix eqv**.

```raku
multi infix:<eqv>(Match:D \a, Match:D \b)
```

Returns `True` if the attributes `pos`, `from` and `orig` for `a` and `b` are equal, and if `made`, `Capture::list` and `Capture::hash` are either the same or both undefined.

# [In ObjAt](#___top "go to top of document")[§](#(ObjAt)_infix_eqv "direct link")

See primary documentation
[in context](/type/ObjAt#infix_eqv)
for **infix eqv**.

```raku
multi infix:<eqv>(ObjAt:D $a, ObjAt:D $b)
```

Returns True if the two ObjAt are the same, that is, if the object they identify is the same.

```raku
my @foo = [2,3,1];
my @bar := @foo;
say @foo.WHICH eqv @bar.WHICH; # OUTPUT: «True␤»
```

# [In Operators](#___top "go to top of document")[§](#(Operators)_infix_eqv "direct link")

See primary documentation
[in context](/language/operators#infix_eqv)
for **infix eqv**.

```raku
sub infix:<eqv>(Any, Any)
```

This could be called an equivalence operator, and it will return `True` if the two arguments are structurally the same, i.e. from the same type and (recursively) contain equivalent values.

```raku
say [1, 2, 3] eqv [1, 2, 3];    # OUTPUT: «True␤»
say Any eqv Any;                # OUTPUT: «True␤»
say 1 eqv 2;                    # OUTPUT: «False␤»
say 1 eqv 1.0;                  # OUTPUT: «False␤»
```

Lazy [`Iterable`](/type/Iterable)s cannot be compared, as they're assumed to be infinite. However, the operator will do its best and return `False` if the two lazy [`Iterable`](/type/Iterable)s are of different types or if only one [`Iterable`](/type/Iterable) is lazy.

```raku
say (1…∞) eqv (1…∞).List; # Both lazy, but different types;   OUTPUT: «False␤»
say (1…∞) eqv (1…3);      # Same types, but only one is lazy; OUTPUT: «False␤»
(try say (1…∞) eqv (1…∞)) # Both lazy and of the same type. Cannot compare; throws.
    orelse say $!.^name;  # OUTPUT: «X::Cannot::Lazy␤»
```

In some cases, it will be able to compare lazy operands, as long as they can be iterated

```raku
my $a = lazy ^2;
my $b = $a;
$a.cache;
say $a eqv $b; # OUTPUT: «True␤»

```

When cached, the two lazy [`Seq`](/type/Seq)s can be iterated over, and thus compared.

The default `eqv` operator even works with arbitrary objects. E.g., `eqv` will consider two instances of the same object as being structurally equivalent:

```raku
my class A {
    has $.a;
}
say A.new(a => 5) eqv A.new(a => 5);  # OUTPUT: «True␤»
```

Although the above example works as intended, the `eqv` code might fall back to a slower code path in order to do its job. One way to avoid this is to implement an appropriate infix `eqv` operator:

```raku
my class A {
    has $.a;
}
multi infix:<eqv>(A $l, A $r) { $l.a eqv $r.a }
say A.new(a => 5) eqv A.new(a => 5);            # OUTPUT: «True␤»
```

Note that `eqv` does not work recursively on every kind of container type, e.g. [`Set`](/type/Set):

```raku
my class A {
    has $.a;
}
say Set(A.new(a => 5)) eqv Set(A.new(a => 5));  # OUTPUT: «False␤»
```

Even though the contents of the two sets are `eqv`, the sets are not. The reason is that `eqv` delegates the equality check to the [`Set`](/type/Set) object which relies on element-wise `===` comparison. Turning the class `A` into a value type ([`ValueObjAt`](/type/ValueObjAt)) by giving it a `WHICH` method produces the expected behavior:

```raku
my class A {
    has $.a;
    method WHICH {
        ValueObjAt.new: "A|$!a.WHICH()"
    }
}
say Set(A.new(a => 5)) eqv Set(A.new(a => 5));  # OUTPUT: «True␤»
```

You can call a single-argument version of the operator by using its full name; it will always return true.

```raku
say infix:<eqv>(33);    # OUTPUT: «True␤»
say infix:<eqv>(False); # OUTPUT: «True␤»

```

# [In Allomorph](#___top "go to top of document")[§](#(Allomorph)_infix_eqv "direct link")

See primary documentation
[in context](/type/Allomorph#infix_eqv)
for **infix eqv**.

```raku
multi infix:<eqv>(Allomorph:D $a, Allomorph:D $b --> Bool:D)
```

Returns `True` if the two `Allomorph` `$a` and `$b` are of the same type, their [`Numeric`](/type/Numeric) values are [equivalent](/routine/eqv) and their [`Str`](/type/Str) values are also [equivalent](/routine/eqv). Returns `False` otherwise.


## dist_cpan-AZAWAWI-MagickWand.md
# MagickWand

This provides a Perl 6 object-oriented [NativeCall](http://doc.perl6.org/language/nativecall)-based API for ImageMagick's
[MagickWand C API](http://www.imagemagick.org/script/magick-wand.php).

## Build Status

| Operating System | Build Status | CI Provider |
| --- | --- | --- |
| Linux / Mac OS X | [Build Status](https://travis-ci.org/azawawi/perl6-magickwand) | Travis CI |
| Windows 7 64-bit | [Build status](https://ci.appveyor.com/project/azawawi/perl6-magickwand/branch/master) | AppVeyor |

## Example

```
use v6;
use MagickWand;

# A new magic wand
my $wand = MagickWand.new;

# Read an image
$wand.read("examples/images/aero1.jpg");

# Lighten dark areas
$wand.auto-gamma;

# And then write a new image
$wand.write("output.png");

# And cleanup on exit
LEAVE {
  $wand.cleanup if $wand.defined;
}

```

For more examples, please see the <examples> folder.
For examples of available image effects, please click
[here](http://www.imagemagick.org/script/examples.php).

## Prerequisites

Please follow the instructions below based on your platform:

### Linux (Debian)

* To install ImageMagick libraries, please run:

```
$ sudo apt install libmagickwand-dev

```

### MacOSX (Darwin)

* To install ImageMagick libraries via [Homebrew](http://brew.sh/), please run:

```
$ brew update
$ brew install imagemagick

```

* To install ImageMagick libraries via [MacPorts](https://www.macports.org/),
  please run:

```
$ sudo port install ImageMagick

```

### Windows

For 64-bit Windows, please install the [`64-bit`](https://www.imagemagick.org/download/binaries/ImageMagick-7.0.8-14-Q16-x64-dll.exe)
DLL installer. Otherwise, use the [`32-bit`](https://www.imagemagick.org/download/binaries/ImageMagick-7.0.8-14-Q16-x86-dll.exe)
version.

Also please remember to enable **"Add to PATH"** option.

## Installation

* Install this module using [zef](https://github.com/ugexe/zef):

```
$ zef install MagickWand

```

## Testing

To run tests:

```
$ prove -ve "perl6 -Ilib"

```

## Author

Ahmad M. Zawawi, azawawi on #perl6, <https://github.com/azawawi/>

## License

MIT License


## formattingcode.md
class Pod::FormattingCode

Pod formatting code

```raku
class Pod::FormattingCode is Pod::Block { }
```

Class for formatting codes in a Pod document.

# [Methods](#class_Pod::FormattingCode "go to top of document")[§](#Methods "direct link")

## [method type](#class_Pod::FormattingCode "go to top of document")[§](#method_type "direct link")

```raku
method type(--> Mu)
```

## [method meta](#class_Pod::FormattingCode "go to top of document")[§](#method_meta "direct link")

```raku
method meta(--> Positional)
```


## dist_zef-japhb-Terminal-QuickCharts.md
[![Actions Status](https://github.com/japhb/Terminal-QuickCharts/actions/workflows/test.yml/badge.svg)](https://github.com/japhb/Terminal-QuickCharts/actions)

# NAME

Terminal::QuickCharts - Simple charts for CLI tools

# SYNOPSIS

```
use Terminal::QuickCharts;

# Chart routines take an array of data points and return an array of
# rendered rows using ANSI terminal codes and Unicode block characters
.say for hbar-chart([5, 10, 15]);

# Horizontal bar charts support 2D data, grouping (default) or stacking the bars
.say for hbar-chart([(1, 2, 3), (4, 5, 6)], :colors< red yellow blue >);
.say for hbar-chart([(1, 2, 3), (4, 5, 6)], :colors< red yellow blue >, :stacked);

# You can also specify optional style and sizing info
.say for hbar-chart([17, 12, 16, 14], :min(10), :max(20));
.say for smoke-chart(@lots-of-data, :style{ lines-every => 5 });

# auto-chart() chooses a chart variant based on specified semantic domain,
# details of the actual data, and available screen size
.say for auto-chart('frame-time', @frame-times);

```

# EXAMPLES

Comparing an animation's performance before and after a round of optimization:

![performance comparison charts](https://user-images.githubusercontent.com/63550/60478723-533b2f00-9c38-11e9-9462-2ef67d1840bf.png)

Result of many small Rakudo optimizations on a standard benchmark's runtime:

![graph of Rakudo optimization results](https://user-images.githubusercontent.com/63550/60484089-0746b500-9c4d-11e9-87fe-4ac4c032ba5e.png)

# DESCRIPTION

Terminal::QuickCharts provides a small library of simple text-output charts, suitable for sprucing up command-line reporting and quick analysis tools. The emphasis here is more on whipuptitude, and less on manipulexity.

This is a *very* early release; expect further iteration on the APIs, and if time permits, bug fixes and additional chart types.

# AUTHOR

Geoffrey Broadwell [gjb@sonic.net](mailto:gjb@sonic.net)

# COPYRIGHT AND LICENSE

Copyright 2019-2021 Geoffrey Broadwell

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.


## pipe.md
class IO::Pipe

Buffered inter-process string or binary stream

```raku
class IO::Pipe is IO::Handle {}
```

An `IO::Pipe` object closely corresponds to a UNIX pipe. It has one end where it consumes string or binary data, and another where it reproduces the same data. It is buffered, so that a write without a read doesn't immediately block.

Pipes can be easily constructed with [sub run and Proc::Async.new](/type/Proc/Async).

# [Methods](#class_IO::Pipe "go to top of document")[§](#Methods "direct link")

## [method close](#class_IO::Pipe "go to top of document")[§](#method_close "direct link")

```raku
method close(IO::Pipe: --> Proc:D)
```

Closes the pipe and returns [`Proc`](/type/Proc) object from which the pipe originates.

## [method IO](#class_IO::Pipe "go to top of document")[§](#method_IO "direct link")

```raku
method IO(IO::Pipe: --> IO::Path:U)
```

Returns an [`IO::Path`](/type/IO/Path) type object.

## [method path](#class_IO::Pipe "go to top of document")[§](#method_path "direct link")

```raku
method path(IO::Pipe: --> IO::Path:U)
```

Returns an [`IO::Path`](/type/IO/Path) type object.

## [method proc](#class_IO::Pipe "go to top of document")[§](#method_proc "direct link")

```raku
method proc(IO::Pipe: --> Proc:D)
```

Returns the [`Proc`](/type/Proc) object from which the pipe originates.


## dist_cpan-FRITH-Math-Libgsl-QuasiRandom.md
[![Build Status](https://travis-ci.org/frithnanth/raku-Math-Libgsl-QuasiRandom.svg?branch=master)](https://travis-ci.org/frithnanth/raku-Math-Libgsl-QuasiRandom)

# NAME

Math::Libgsl::QuasiRandom - An interface to libgsl, the Gnu Scientific Library - Quasi-Random Sequences.

# SYNOPSIS

```
use Math::Libgsl::QuasiRandom;
use Math::Libgsl::Constants;

my Math::Libgsl::QuasiRandom $q .= new: :type(SOBOL), :2dimensions;
$q.get».say for ^10;

```

# DESCRIPTION

Math::Libgsl::QuasiRandom is an interface to the Quasi-Random Sequences of libgsl, the Gnu Scientific Library.

### new(Int :$type, Int :$dimensions)

The constructor allows two parameters, the quasi-random sequence generator type and the dimensions. One can find an enum listing all the generator types in the Math::Libgsl::Constants module.

### init()

This method re-inits the sequence.

### get(--> List)

Returns the next item in the sequence as a List of Nums.

### name(--> Str)

This method returns the name of the current quasi-random sequence.

### copy(Math::Libgsl::QuasiRandom $src)

This method copies the source generator **$src** into the current one and returns the current object, so it can be concatenated. The generator state is also copied, so the source and destination generators deliver the same values.

### clone(--> Math::Libgsl::QuasiRandom)

This method clones the current object and returns a new object. The generator state is also cloned, so the source and destination generators deliver the same values.

```
my $q = Math::Libgsl::QuasiRandom.new;
my $clone = $q.clone;

```

# C Library Documentation

For more details on libgsl see <https://www.gnu.org/software/gsl/>. The excellent C Library manual is available here <https://www.gnu.org/software/gsl/doc/html/index.html>, or here <https://www.gnu.org/software/gsl/doc/latex/gsl-ref.pdf> in PDF format.

# Prerequisites

This module requires the libgsl library to be installed. Please follow the instructions below based on your platform:

## Debian Linux

```
sudo apt install libgsl23 libgsl-dev libgslcblas0

```

That command will install libgslcblas0 as well, since it's used by the GSL.

## Ubuntu 18.04

libgsl23 and libgslcblas0 have a missing symbol on Ubuntu 18.04. I solved the issue installing the Debian Buster version of those three libraries:

* <http://http.us.debian.org/debian/pool/main/g/gsl/libgslcblas0_2.5+dfsg-6_amd64.deb>
* <http://http.us.debian.org/debian/pool/main/g/gsl/libgsl23_2.5+dfsg-6_amd64.deb>
* <http://http.us.debian.org/debian/pool/main/g/gsl/libgsl-dev_2.5+dfsg-6_amd64.deb>

# Installation

To install it using zef (a module management tool):

```
$ zef install Math::Libgsl::QuasiRandom

```

# AUTHOR

Fernando Santagata [nando.santagata@gmail.com](mailto:nando.santagata@gmail.com)

# COPYRIGHT AND LICENSE

Copyright 2020 Fernando Santagata

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.


## pickpairs.md
pickpairs

Combined from primary sources listed below.

# [In role Baggy](#___top "go to top of document")[§](#(role_Baggy)_method_pickpairs "direct link")

See primary documentation
[in context](/type/Baggy#method_pickpairs)
for **method pickpairs**.

```raku
multi method pickpairs(Baggy:D: --> Pair:D)
multi method pickpairs(Baggy:D: $count --> Seq:D)
```

Returns a [`Pair`](/type/Pair) or a [`Seq`](/type/Seq) of [`Pair`](/type/Pair)s depending on the version of the method being invoked. Each [`Pair`](/type/Pair) returned has an element of the invocant as its key and the element's weight as its value. The elements are 'picked' without replacement. If `*` is passed as `$count`, or `$count` is greater than or equal to the number of [elements](#method_elems) of the invocant, then all element/weight [`Pair`](/type/Pair)s from the invocant are returned in a random sequence.

Note that each `pickpairs` invocation maintains its own private state and has no effect on subsequent `pickpairs` invocations.

```raku
my $breakfast = bag <eggs bacon bacon bacon>;
say $breakfast.pickpairs;                         # OUTPUT: «eggs => 1␤»
say $breakfast.pickpairs(1);                      # OUTPUT: «(bacon => 3)␤»
say $breakfast.pickpairs(*);                      # OUTPUT: «(eggs => 1 bacon => 3)␤»
```

# [In role Setty](#___top "go to top of document")[§](#(role_Setty)_method_pickpairs "direct link")

See primary documentation
[in context](/type/Setty#method_pickpairs)
for **method pickpairs**.

```raku
multi method pickpairs(Setty:D: --> Pair:D)
multi method pickpairs(Setty:D: $count --> Seq:D)
```

Returns a [`Pair`](/type/Pair) or a [`Seq`](/type/Seq) of [`Pair`](/type/Pair)s depending on the candidate of the method being invoked. Each [`Pair`](/type/Pair) returned has an element of the invocant as its key and `True` as its value. In contrast to [grabpairs](#method_grabpairs), the elements are 'picked' without replacement.

If `*` is passed as `$count`, or `$count` is greater than or equal to the number of [elements](#method_elems) of the invocant, then all element/`True` [`Pair`](/type/Pair)s from the invocant are returned in a random sequence; i.e. they are returned shuffled;

Note that each `pickpairs` invocation maintains its own private state and has no effect on subsequent `pickpairs` invocations.

```raku
my $numbers = set (4, 2, 3);
say $numbers.pickpairs;                           # OUTPUT: «4 => True␤»
say $numbers.pickpairs(1);                        # OUTPUT: «(3 => True)␤»
say $numbers.pickpairs(*);                        # OUTPUT: «(2 => True 4 => True 3 => True)␤»
```


## usage.md
class Telemetry::Instrument::Usage

Instrument for collecting getrusage data

```raku
class Telemetry::Instrument::Usage { }
```

**Note:**  This class is a Rakudo-specific feature and not standard Raku.

Objects of this class are generally not created by themselves, but rather through making a [snap](/type/Telemetry)shot.

## [Useful readings](#class_Telemetry::Instrument::Usage "go to top of document")[§](#Useful_readings "direct link")

This class provides the following generally usable readings (in alphabetical order):

* cpu

The total amount of CPU time (in microseconds), essentially the sum of `cpu-user` and `cpu-sys`.

* cpu-sys

The number of microseconds of CPU used by the system.

* cpu-user

The number of microseconds of CPU used by the user program.

* cpus

The number of CPU's active, essentially `cpu` divided by `wallclock`.

* max-rss

The maximum resident set size (in KiB).

* util%

Percentage of CPU utilization, essentially 100 \* `cpus` / number of CPU cores.

* wallclock

The time the program has been executing (in microseconds).

## [Less useful readings](#class_Telemetry::Instrument::Usage "go to top of document")[§](#Less_useful_readings "direct link")

The following readings may or may not contain sensible information, mostly depending on hardware and OS being used. Please check your local `getrusage` documentation for their exact meaning:

｢text｣ without highlighting

```

```

name        getrusage struct name
====        =====================
max-rss     ru_maxrss
ix-rss      ru_ixress
id-rss      ru_idrss
is-rss      ru_isrss
minf        ru_minflt
majf        ru_majflt
nswp        ru_nswap
inb         ru_inblock
outb        ru_oublock
msnd        ru_msgsnd
mrcv        ru_msgrcv
nsig        ru_nsignals
volcsw      ru_nvcsw
invcsw      ru_nivcsw

```

```


## dist_zef-PowellDean-Locale-Codes-Country.md
# Locale::Codes::Country

Locale::Codes::Country is a first attempt at creating a pure Raku implementation
of the Perl 5 module of the same name found on CPAN. This version extends
the functionality of the original version.

# Requirements

Rakudo (Tested with the 2024.01 release).

# Installation

Use zef. The command: `zef install Locale-Codes-Country` should work.

# What's it for?

Locale::Codes::Country is an implementation of the ISO3166 standard, which defines
codes for the names of countries, dependent territories, etc. There are
essentially four types of codes associated with each country/area:

* LOCALE\_CODE\_ALPHA\_2 defines a unique 2 character code for each country/area
* LOCALE\_CODE\_ALPHA\_3 defines a unique 3 character code
* LOCALE\_CODE\_NUMERIC defines a numeric code (between 000 and 999) for each
  country/area
* LOCALE\_CODE\_DOM defines the IANA assigned Top Level Domain for a country.
  For most countrues this just the LOCALE\_CODE\_ALPHA\_2 code in lower case
  with a leading dot, but every now and again there is a difference. I may
  not have caught those yet ;-)

For each of the constants listed above there is an equivalent string. Respectively:

* 'alpha-2'
* 'alpha-3'
* 'numeric'
* 'dom'

Using Locale::Codes::Country, you may lookup a country name by its ISO3166-2,
ISO3166-3 or ISO3166-Numeric defined code. You may also look up a country's
ISO-assigned code using the full country name. You may also lookup one
of the other ISO-defined codes by passing in any of the other unique values.

# Examples

```
use Locale::Codes::Country;

say codeToCountry("BGD"); # will print 'BANGLADESH'
say codeToCountry("CA"); # will print 'CANADA'. LOCALE_CODE_ALPHA_2 is default
say countryToCode("Austria",LOCALE_CODE_NUMERIC) # will print "040"
say codeToCode(70, "alpha-3"); # will print BIH (Bosnia and Herzegovina)

```

# Future

I may in the near future add other codes such as IOC designations, or FIPS
codes to the mix.

# Testing

Basic tests. Not extensive, but there are a few.

Run `prove6 --lib t -v` or `zef test .`

# Contributing

Comments and Pull Requests are always welcome.

# License and Author

The Artistic 2.0 License (Artistic-2)

Copyright (c) 2016-2024 Dean Powell [PowellDean@gmail.com](mailto:PowellDean@gmail.com)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.


## splice.md
splice

Combined from primary sources listed below.

# [In Array](#___top "go to top of document")[§](#(Array)_routine_splice "direct link")

See primary documentation
[in context](/type/Array#routine_splice)
for **routine splice**.

```raku
multi        splice(@list,   $start = 0, $elems?, *@replacement --> Array)
multi method splice(Array:D: $start = 0, $elems?, *@replacement --> Array)
```

Deletes `$elems` elements starting from index `$start` from the `Array`, returns them and replaces them by `@replacement`. If `$elems` is omitted or is larger than the number of elements starting from `$start`, all the elements starting from index `$start` are deleted. If both `$start` and `$elems` are omitted, all elements are deleted from the `Array` and returned.

Each of `$start` and `$elems` can be specified as a [`Whatever`](/type/Whatever) or as a [`Callable`](/type/Callable) that returns an [`Int`](/type/Int)-compatible value: this returned value is then used as the corresponding argument to the `splice` routine.

A [`Whatever`](/type/Whatever) `$start` uses the number of elements of `@list` (or invocant). A [`Callable`](/type/Callable) `$start` is called with one argument—the number of elements in `@list` (or `self`).

A [`Whatever`](/type/Whatever) `$elems` deletes from `$start` to end of `@list` (or `self`) (same as no `$elems`). A [`Callable`](/type/Callable) `$elems` is called with one argument—the number of elements in `@list` (or `self`) minus the value of `$start`.

Example:

```raku
my @foo = <a b c d e f g>;
say @foo.splice(2, 3, <M N O P>);        # OUTPUT: «[c d e]␤»
say @foo;                                # OUTPUT: «[a b M N O P f g]␤»
```

It can be used to extend an array by simply splicing in more elements than the current size (since version 6.d)

```raku
my @foo = <a b c d e f g>;
say @foo.splice(6, 4, <M N O P>);       # OUTPUT: «[g]␤»
say @foo;                               # OUTPUT: «[a b c d e f M N O P]␤»

```

The following equivalences hold (assuming that `@a.elems ≥ $i`):

｢text｣ without highlighting

```

```

@a.push($x, $y)      @a.splice: *  , *, $x, $y
@a.pop               @a.splice: *-1,
@a.shift             @a.splice: 0  , 1,
@a.unshift($x, $y)   @a.splice: 0  , 0, $x, $y
@a[$i] = $y          @a.splice: $i , 1, $y,

```

```

As mentioned above, a [`Whatever`](/type/Whatever) or [`Callable`](/type/Callable) object can be provided for both the `$start` and `$elems` parameters. For example, we could use either of them to remove the second to last element from an array provided it's large enough to have one:

```raku
my @foo = <a b c d e f g>;
say @foo.splice: *-2, *-1;           # OUTPUT: «[f]␤»
say @foo;                            # OUTPUT: «[a b c d e g]␤»

my &start     = -> $n { $n - 2 };
my &elems-num = -> $m { $m - 1 };
say @foo.splice: &start, &elems-num; # OUTPUT: «[e]␤»
say @foo;                            # OUTPUT: «[a b c d g]␤»
```

# [In role Buf](#___top "go to top of document")[§](#(role_Buf)_method_splice "direct link")

See primary documentation
[in context](/type/Buf#method_splice)
for **method splice**.

```raku
method splice( Buf:D: $start = 0, $elems?, *@replacement --> Buf)
```

Substitutes elements of the buffer by other elements, returning a buffer with the removed elements.

```raku
my $bú = Buf.new( 1, 1, 2, 3, 5 );
say $bú.splice:  0, 3, <3 2 1>;  # OUTPUT: «Buf:0x<01 01 02>␤»
say $bú.raku;                    # OUTPUT: «Buf.new(3,2,1,3,5)␤»
```


## dist_zef-FRITH-Net-Whois.md
[![Actions Status](https://github.com/frithnanth/Raku-Net-Whois/actions/workflows/test.yml/badge.svg)](https://github.com/frithnanth/Raku-Net-Whois/actions)

# NAME

Net::Whois - Raku interface to the Whois service

# SYNOPSIS

```
use Net::Whois;

my Net::Whois $w .= new;
my %h = $w.query: $who, $using;
for %h.kv -> $k, $v { say "$k => $v[*]" }

```

# DESCRIPTION

Net::Whois is an interface to the Whois service

This is a very simple module that does what I just happened to need.

### new()

The constructor takes no arguments.

### multi method query(Str:D $who where { $\_ ~~ IP | Domain or die 'Not a valid IP or domain name' }, Str:D $server, Bool :$raw! --> List)

### multi method query(Str:D $who where { $\_ ~~ IP | Domain or die 'Not a valid IP or domain name' }, Str:D $server, Bool :$multiple --> Hash)

### multi method query(Str:D $who where { $\_ ~~ IP | Domain or die 'Not a valid IP or domain name' }, \*@servers, Bool :$multiple, Bool :$raw --> Hash)

The first form of the method looks for the **$who** domain, using the chosen **$server** and returns a **List** of values. If the **:$raw** flag is used then the result is returned verbatim.

The second form returns a **Hash** of the whois fields. The whois output may consist of several sections; if the **:$multiple** flag is used the values of the same-named field are concatenated into the same value string.

The third form takes a list of servers to query. It returns a **Hash** whose keys are the name of the server and the values are the hashes returned by the second form of the method, or the lists returned by the first form of the method if the **:$raw** flag has been used.

# Installation

To install it using zef (a module management tool):

```
$ zef install Net::Whois

```

# AUTHOR

Fernando Santagata [nando.santagata@gmail.com](mailto:nando.santagata@gmail.com)

# COPYRIGHT AND LICENSE

Copyright 2023 Fernando Santagata

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.


## dist_zef-antononcube-Graphviz-DOT-Grammar.md
# Graphviz::DOT::Grammar

Raku package with a parser and interpreters of Graphviz DOT language.

Languages and formats DOT is translated to:

* DONE DOT layout formats
  * SVG, EPS, JSON, plain, etc.
* DONE PlantUML
  * PlantUML uses DOT language, so it was very short and easy format implementation.
* DONE Mermaid-JS
* [-] TODO Mathematica
  * DONE Basic vertexes and edges
  * TODO Vertex styles
  * TODO Edge styles
* TODO Raku
  * Translation to Raku graphs, [AAp1]
  * Based on the Mathematica actions

---

## Usage examples

Here is a graph (see [AAp1]):

```
use Graph::HexagonalGrid;

my $g = Graph::HexagonalGrid.new(1, 1);

```

```
# Graph(vertexes => 6, edges => 6, directed => False)

```

Translate to Mermaid-JS:

```
use Graphviz::DOT::Grammar;
$g.dot ==> dot-interpret(a=>'mermaid')

```

```
graph TB
v0["1"]
v1["4"]
v2["5"]
v3["0"]
v4["3"]
v5["2"]
v4 --- v2
v1 --- v2
v3 --- v5
v5 --- v1
v0 --- v4
v3 --- v0

```

Translate to Mathematica:

```
$g.dot ==> dot-interpret(a=>'Mathematica')

```

```
Graph[{}, {UndirectedEdge["3", "5"], UndirectedEdge["4", "5"], UndirectedEdge["0", "2"], UndirectedEdge["2", "4"], UndirectedEdge["1", "3"], UndirectedEdge["0", "1"]}]

```

---

## CLI

The package provides the Command Line Interface (CLI) script `from-dot`. Here is its usage message:

```
from-dot --help

```

```
# Usage:
#   from-dot <text> [-t|--to=<Str>] [-o|--output=<Str>] -- Converts Graphviz DOT language texts or files into Mermaid-JS, Mathematica, Markdown, JSON, Raku, or SVG files.
#
#     <text>               Input file or DOT spec.
#     -t|--to=<Str>        Format to convert to. (One of 'json', 'mathematica', 'mermaid', 'raku', 'svg', or 'Whatever'.) [default: 'Whatever']
#     -o|--output=<Str>    Output file; if an empty string then the result is printed to stdout. [default: '']

```

---

## References

[AAp1] Anton Antonov,
[Graph Raku package](https://github.com/antononcube/Raku-Graph),
(2024),
[GitHub/antononcube](https://github.com/antononcube).


## dist_zef-lizmat-IRC-Client-Plugin-Rakkable.md
[![Actions Status](https://github.com/lizmat/IRC-Client-Plugin-Rakkable/actions/workflows/linux.yml/badge.svg)](https://github.com/lizmat/IRC-Client-Plugin-Rakkable/actions) [![Actions Status](https://github.com/lizmat/IRC-Client-Plugin-Rakkable/actions/workflows/macos.yml/badge.svg)](https://github.com/lizmat/IRC-Client-Plugin-Rakkable/actions) [![Actions Status](https://github.com/lizmat/IRC-Client-Plugin-Rakkable/actions/workflows/windows.yml/badge.svg)](https://github.com/lizmat/IRC-Client-Plugin-Rakkable/actions)

# NAME

IRC::Client::Plugin::Rakkable - local rak searches by bot

# SYNOPSIS

```
use IRC::Client;
use IRC::Client::Plugin::Rakkable;

.run with IRC::Client.new(
  :nick<Rakkable>,
  :host<irc.libera.chat>,
  :channels<#raku-dev #moarvm>,
  :plugins(IRC::Client::Plugin::Rakkable.new(
  )),
);

```

# DESCRIPTION

The `IRC::Client::Plugin::Rakkable` distribution provides an interface to run local `rak` searches and produce results of them on IRC channels (and gist results for further perusal).

# AUTHOR

Elizabeth Mattijsen [liz@raku.rocks](mailto:liz@raku.rocks)

Source can be located at: <https://github.com/lizmat/IRC-Client-Plugin-Rakkable> . Comments and Pull Requests are welcome.

If you like this module, or what I'm doing more generally, committing to a [small sponsorship](https://github.com/sponsors/lizmat/) would mean a great deal to me!

# COPYRIGHT AND LICENSE

Copyright 2025 Elizabeth Mattijsen

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.


## dist_zef-lizmat-Zef-Configuration.md
[![Actions Status](https://github.com/lizmat/Zef-Configuration/actions/workflows/linux.yml/badge.svg)](https://github.com/lizmat/Zef-Configuration/actions) [![Actions Status](https://github.com/lizmat/Zef-Configuration/actions/workflows/macos.yml/badge.svg)](https://github.com/lizmat/Zef-Configuration/actions) [![Actions Status](https://github.com/lizmat/Zef-Configuration/actions/workflows/windows.yml/badge.svg)](https://github.com/lizmat/Zef-Configuration/actions)

# NAME

Zef::Configuration - Manipulate Zef configurations

# SYNOPSIS

```
use Zef::Configuration;

my $zc = Zef::Configuration.new;         # factory settings

my $zc = Zef::Configuration.new(:user);  # user settings

my $zc = Zef::Configuration.new($io);    # from a config file path

```

Or use the command-line interface:

```
$ zef-configure

$ zef-configure enable something

$ zef-configure disable something

$ zef-configure reset

```

# DESCRIPTION

Zef::Configuration is a class that allows you to manipulate the configuration of Zef programmatically. Perhaps more importantly, it provides a command-line script `zef-configure` that allows you to perform simple actions to Zef's config-files.

# COMMAND-LINE INTERFACE

## General named arguments

### config-path

```
$ zef-configure --config-path=~/.zef/config.json

```

The `config-path` named argument can be used to indicate the location of the configuration to read from / write to.

### dry-run

```
$ zef-configure enable rea --dry-run

```

The `dry-run` named argument can be used to inhibit writing any changes to the configuration file.

## Possible actions

The `zef-configure` script that is installed with this module, allows for the following actions. Please note that sub-commands (such as "enable") can be shortened as long as they are not ambiguous..

## Getting an overview

```
$ zef-configure

```

Calling `zef-configure` without any parameters (except maybe the `config-path` parameter) will show an overview of all the settings in the configuration. The names shown can be used to indicate what part of the configuration you want changed.

## Enabling a setting

```
$ zef-configure enable rea

```

If a setting is disabled, then you can enable it with the `enable` directive, followed by the name of the setting you want enabled.

## Disabling a setting

```
$ zef-configure disable cpan

```

If a setting is enabled, then you can disable it with the `disable` directive, followed by the name of the setting you want disabled.

## Reset to factory settings

```
$ zef-configure reset

```

To completely reset a configuration to the "factory" settings, you can use the `reset` directive.

```
$ zef-configure reset --config-path=~/.zef/config.json

```

You can also use this function in combination with `config-=path` to create a configuration file with the "factory" settings.

# GENERAL NOTES

All of the attributes of the classes provided by this distribution, are either an `Array` (and thus mutable), or a an attribute with the `is rw` trait applied to it. This is generally ok, since it is expected that this module will mostly only be used by a relatively short-lived CLI.

Note that if you change an object that is based on one of the default objects, you will be changing the default as well. This may or may not be what you want. If it is not, then you should probably first create a `clone` of the object, or use the `clone` method with named arguments to create a clone with changed values.

# METHODS ON ALL CLASSES

All of these classes provided by this distribution provide these methods (apart from the standard methods provided by Raku).

### new

Apart from the normal way of creating objects with named arguments, one can also specify a hash as returned with `data` to create an object.

### data

Return a Raku data-structure for the object. This is usually a `Map`, but can also be a `List`.

### json

Return a pretty JSON string with sorted keys for the object. Takes named parameters `:!pretty` and `:!sorted-keys` should you not want the JSON string to be pretty, or have sorted keys.

### status

Return a string describing the status of the object.

# METHODS ON MOST CLASSES

With the exception of the `Zef::Configuration`, `Zef::Configuration::License` and `Zef::Configuration::RepositoryGroup` classes, the following attributes / methods are always provided.

### short-name

A name identifying the object. **Must** be specified in the creation of the object.

### module

The name of the Raku module to be used by this object. **Must** be specified in the creation of the object unless there is a default available for the given object.

### enabled

A boolean indicating whether the object is enabled. Defaults to `True`.

### comment

Any comments applicable to this object. Defaults to the `Str` type object.

# Zef::Configuration

The `Zef::Configuration` class contains all information about a configuration of `Zef`. A `Zef::Configuration` object can be made in 6 different ways:

## CREATION

```
my $zc = Zef::Configuration.new;         # "factory settings"

my $zc = Zef::Configuration.new(:user);  # from the user's Zef config

my $zc = Zef::Configuration.new($io);    # from a file as an IO object

my $zc = Zef::Configuration.new($json);  # a string containing JSON

my $zc = Zef::Configuration.new(%hash);  # a hash, as decoded from JSON

my $zc = Zef::Configuration.new:         # named arguments to set attributes
  ConfigurationVersion => 2,
  RootDir              => 'foo/bar',
  ...
;

```

## ATTRIBUTES / METHODS

It contains the following attributes / methods:

### ConfigurationVersion

The version of the configuration. Defaults to `1`.

### RootDir

The directory in which Zef keeps all of its information. Defaults to `$*HOME/.zef`.

### StoreDir

The directory in which Zef keeps all of the information that has been downloaded. Defaults to `RootDir ~ "/store"`.

### TempDir

The directory in which Zef stores temporary files. Defaults to `RootDir ~ "/tmp"`.

### License

A `Zef::Configuration::License` object. Defaults to `Zef::Configuration.default-licenses<default>`.

### Repository

An array of `Zef::Configuration::RepositoryGroup` objects in the order in which they will be checked when searching for distributions. Defaults to `Zef::Configuration.default-repository-groups` in the order: `primary`, `secondary`, `tertiary`, `last`.

### Fetch

An array of `Zef::Configuration::Fetch` objects. Defaults to `Zef::Configuration.default-fetch`.

### Extract

An array of `Zef::Configuration::Extract` objects. Defaults to `Zef::Configuration.default-extract`.

### Build

An array of `Zef::Configuration::Build` objects. Defaults to `Zef::Configuration.default-build`.

### Test

An array of `Zef::Configuration::Test` objects. Defaults to `Zef::Configuration.default-test`.

### Report

An array of `Zef::Configuration::Report` objects. Defaults to `Zef::Configuration.default-report`.

### Install

An array of `Zef::Configuration::Install` objects. Defaults to `Zef::Configuration.default-install`.

### DefaultCUR

An array of strings indicating which `CompUnitRepository`(s) to be used when installing a module. Defaults to `Zef::Configuration.default-defaultCUR`.

## ADDITIONAL CLASS METHODS

### is-configuration-writeable

Class method that takes an `IO::Path` of a configuration file (e.g. as returned by `user-configuration`) and returns whether that file is safe to write to (files part of the installation should not be written to).

### new-user-configuration

Class method that returns an `IO::Path` with location at which a new configuration file can be stored, to be visible with future default incantations of Zef. Returns `Nil` if no such location could be found.

### user-configuration

Class method that returns an `IO::Path` object of the configuration file that Zef is using by default.

## ADDITIONAL INSTANCE METHODS

### default-...

Instance methods for getting the default state of a given aspect of the `Zef::Configuration` object.

* default-license
* default-repository
* default-repositorygroup
* default-fetch
* default-extract
* default-build
* default-test
* default-report
* default-install
* default-defaultCUR

Each of these can either called without any arguments: in that case a `Map` will be returned with each of the applicable objects, associated with a **tag**. Or it can be called with one of the valid tags, in which case the associated object will be returned.

### object-from-tag

Instance method that allows selection of an object by its tag (usually the `short-name`) in one of the attributes of the `Zef::Configuration` object.

Tags can be specified just by themselves if they are not ambiguous, else the group name should be prefixed with a hyphen inbetween (e.g. `license-default`).

If an ambiguous tag is given, then a `List` of `Pair`s will be returned in which the key is a group name, and the value is the associated object.

If only one object was found, then that will be returned. If no objects were found, then `Nil` will be returned.

## Zef::Configuration::License

Contains which licenses are `blacklist`ed and which ones are `whitelist`ed. Defaults to no blacklisted licenses, and `"*"` in the whitelist, indicating that any license will be acceptable. Does not contain any other information.

## Zef::Configuration::Repository

Contains the information about a repository in which distributions are located. It provided these additional attributes / methods:

### name

The full name of the repository. Defaults to the `short-name`.

### module

The Raku module to be used for handling the `Zef::Configuration::Repository` defaults to `Zef::Repository::Ecosystems`.

### auto-update

The number of hours that should pass until a local copy of the distribution information about a repository should be considered stale. Defaults to `1`.

### uses-path

A boolean indicating whether the `path` field in the distribution should be used to obtain a distribution. Defaults to `False`, unless the repository's `short-name` equals `zef`.

### mirrors

An array of URLs that should be used to fetch the information about all the distributions in the repository. **Must** be specified with the URL of at least one mirror if `auto-update` has been (implicitely) set to a non-zero value.

## Zef::Configuration::RepositoryGroup

Contains a list of `Zef::Configuration::Repository` objects in the order in which a search should be done for modules. Does not contain any other information.

## Zef::Configuration::Fetch

Information on how to fetch a distribution from a `Zef::Configuration::Repository`.

## Zef::Configuration::Extract

Information on how to extract information from a fetched distribution.

## Zef::Configuration::Build

Information on how to build modules from a fetched distribution.

## Zef::Configuration::Test

Information on how to perform tesing on a fetched distribution.

## Zef::Configuration::Report

Information about how a report of a distribution test should be reported.

## Zef::Configuration::Install

Information about how a distribution should be installed.

# AUTHOR

Elizabeth Mattijsen [liz@raku.rocks](mailto:liz@raku.rocks)

Source can be located at: <https://github.com/lizmat/Zef-Configuration> . Comments and Pull Requests are welcome.

If you like this module, or what I’m doing more generally, committing to a [small sponsorship](https://github.com/sponsors/lizmat/) would mean a great deal to me!

# COPYRIGHT AND LICENSE

Copyright 2022, 2023, 2024, 2025 Elizabeth Mattijsen

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.


## 5to6-overview.md
Perl to Raku guide - overview

How do I do what I used to do?

These documents should not be mistaken for a beginner tutorial or a promotional overview of Raku (née Perl 6); it is intended as a technical reference for Raku learners with a strong Perl background and for anyone porting Perl code to Raku.

# [Raku in a nutshell](#Perl_to_Raku_guide_-_overview "go to top of document")[§](#Raku_in_a_nutshell "direct link")

[Raku in a Nutshell](/language/5to6-nutshell) provides a quick overview of things changed in syntax, operators, compound statements, regular expressions, command-line flags, and various other bits and pieces.

# [Syntactic differences](#Perl_to_Raku_guide_-_overview "go to top of document")[§](#Syntactic_differences "direct link")

The [Syntax section](/language/5to6-perlsyn) provides an overview of the syntactic differences between Perl and Raku: how it is still mostly free form, additional ways to write comments, and how `switch` is very much a Raku thing.

# [Operators in Raku](#Perl_to_Raku_guide_-_overview "go to top of document")[§](#Operators_in_Raku "direct link")

The [Operators section](/language/5to6-perlop) guides you from the operators in [Perl's perlop](https://metacpan.org/pod/distribution/perl/pod/perlop.pod) to the equivalent in Raku.

# [Functions in Raku](#Perl_to_Raku_guide_-_overview "go to top of document")[§](#Functions_in_Raku "direct link")

The [Functions section](/language/5to6-perlfunc) describes all of the Perl functions and their Raku equivalent and any differences in behavior. It also provides references to ecosystem modules that provide the Perl behavior of functions, either existing in Raku with slightly different semantics (such as `shift`), or non-existing in Raku (such as `tie`).

# [Special variables in Raku](#Perl_to_Raku_guide_-_overview "go to top of document")[§](#Special_variables_in_Raku "direct link")

The [Special Variables section](/language/5to6-perlvar) describes if and how a lot of Perl's special (punctuation) variables are supported in Raku.


## dist_zef-jjmerelo-GitHub-Actions.md
# GitHub::Actions for Raku [Test in a Raku container - template](https://github.com/JJ/raku-github-actions/actions/workflows/test.yaml)

Use the GitHub actions console API easily from Raku. Essentially, a port to
Raku of the [equivalent Perl module](https://metacpan.org/pod/GitHub::Actions). It's mainly intended to be run inside the [Raku
container for GitHub actions](https://github.com/JJ/alpine-raku), but can of
course be used independently.

## Installing

Install it the usual way, using `zef`:

```
zef install GitHub::Actions

```

Also use it from the companion Docker image,

```
docker pull --rm -it --entrypoint=/bin/sh ghcr.io/jj/raku-github-actions:latest

```

## Running

This is a version derived from the base [Raku image for
GHA](ghcr.io/jj/raku-zef-gha) with this module and its dependencies
installed. You can use it directly in your GitHub actions, for instance like
this:

```
      - name: Test output
        id: output_test
        shell: raku {0}
        run:
          use GitHub::Actions;
          set-output( 'FOO', 'BAR');

```

Check [the Pod6 here](lib/GitHub/Actions.rakumod) for methods available.

## Synopsis

```

use GitHub::Actions:

say %github; # Contains all GITHUB_xyz variables

set-output('FOO','BAR');
set-output('FOO'); # Empty value
set-env("FOO", "bar");
debug('FOO');
error('FOO');
warning('FOO');

error-on-file('FOO', 'foo.pl', 1,1 );

warning-on-file('FOO', 'foo.raku', 1,1 );

# sets group
start-group( "foo" );
warning("bar");
end-group;

```

## See also

Created from the
[Raku distribution template](https://github.com/JJ/raku-dist-template).

## License

(c) JJ Merelo, [jj@raku.org](mailto:jj@raku.org), 2022
Licensed, under the Artistic 2.0 License (the same as Raku itself).


## dist_zef-lizmat-ValueTypeCache.md
[![Actions Status](https://github.com/lizmat/ValueTypeCache/actions/workflows/linux.yml/badge.svg)](https://github.com/lizmat/ValueTypeCache/actions) [![Actions Status](https://github.com/lizmat/ValueTypeCache/actions/workflows/macos.yml/badge.svg)](https://github.com/lizmat/ValueTypeCache/actions) [![Actions Status](https://github.com/lizmat/ValueTypeCache/actions/workflows/windows.yml/badge.svg)](https://github.com/lizmat/ValueTypeCache/actions)

# NAME

ValueTypeCache - A role to cache Value Type classes

# SYNOPSIS

```
use ValueTypeCache;

sub id(%h --> Str:D) {
    %h<x> //= 0;
    %h<y> //= 0;
    "%h<x>,%h<y>"
}

class Point does ValueTypeCache[&id] {
    has $.x;
    has $.y;
}

say Point.new.WHICH;  # Point|0,0

# fill a bag with random Points
my $bag = bag (^1000).map: {
  Point.new: x => (-10..10).roll, y => (-10..10).roll
}
say $bag.elems;  # less than 1000

```

# DESCRIPTION

The `ValueTypeCache` distribution provides a `ValueTypeCache` role that mixes the logic of creating a proper ValueType class **and** making sure that each unique ValueType only exists once in memory, into a single class.

The role takes a `Callable` parameterization to indicate how a unique ID should be created from the parameters given (as a hash) with the call to the `new` method. You can also adapt the given hash making sure any default values are properly applied. If there's already an object created with the returned ID, then no new object will be created but the one from the cache will be returned.

A class is considered to be a value type if the `.WHICH` method returns an object of the `ValueObjAt` class: that then indicates that objects that return the same `WHICH` value, are in fact identical and can be used interchangeably.

This is specifically important when using set operators (such as `(elem)`, or `Set`s, `Bag`s or `Mix`es, or any other functionality that is based on the `===` operator functionality, such as `unique` and `squish`.

The format of the value that is being returned by `WHICH` is only valid during a run of a process. So it should **not** be stored in any permanent medium.

# AUTHOR

Elizabeth Mattijsen [liz@raku.rocks](mailto:liz@raku.rocks)

Source can be located at: <https://github.com/lizmat/ValueTypeCache> . Comments and Pull Requests are welcome.

If you like this module, or what I’m doing more generally, committing to a [small sponsorship](https://github.com/sponsors/lizmat/) would mean a great deal to me!

# COPYRIGHT AND LICENSE

Copyright 2020, 2021, 2024, 2025 Elizabeth Mattijsen

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.


## dist_zef-jjmerelo-IO-Capture-Simple.md
# IO::Capture::Simple

This is a Raku implementation of IO capturing module.

It provides two modules, [`IO::Capture::Simple`](lib/IO/Capture/Simple.pm6) and [`Test::IO::Capture`](lib/Test/IO/Capture.pm6), to capture and test the output of commands.

## Original author

This module was created originally by [Filip Sergot](https://github.com/sergot/IO-Capture-Simple), and has been forked respecting its free License

## License

This code is (c) Filip Sergot, 2018, JJ Merelo 2022. It's released under the
Artistic 2.0 license.