## dist_cpan-BDUGGAN-Jupyter-Kernel.md
## Jupyter::Kernel for Raku

[![Binder](https://binder.pangeo.io/badge_logo.svg)](https://mybinder.org/v2/gh/bduggan/p6-jupyter-kernel/master?filepath=hello-world.ipynb)

![autocomplete](https://user-images.githubusercontent.com/58956/29986517-c6a2020e-8f31-11e7-83da-086ad18bc662.gif)

This is a pure Raku implementation of a Raku kernel for Jupyter clients¹.

Jupyter notebooks provide a web-based (or console-based)
Read Eval Print Loop (REPL) for running code and serializing input and output.

## REALLY QUICK START

[Binder](https://mybinder.org/) provides a way to instantly launch a Docker
image and open a notebook². Click `launch | binder` above
to start this kernel with a sample notebook. (See below
for similar alternatives.)

## QUICK START

* [Installation](#Installation)
* [Configuration](#Configuration)
* [Running](#Running)

### Installation

You'll need to install zmq. Note that currently, version 4.1 is
recommended by Net::ZMQ (though 4.2 is installed by, e.g. homebrew).
If you run into stability issues, you may need to downgrade.

```
brew install zmq           # on OS/X
apt-get install libzmq-dev # on Ubuntu

```

You'll also want jupyter, for the front end:

```
pip install jupyter

```

Finally, install `Jupyter::Kernel`:

```
zef install Jupyter::Kernel

```

At the end of the above installation, you'll see the location
of the `bin/` directory which has `jupyter-kernel.raku`. Make
sure that is in your `PATH`.

### Configuration

#### Server Configuration

To generate a configuration directory, and to install a kernel
config file and icons into the default location:

```
jupyter-kernel.raku --generate-config

```

* Use `--location=XXX` to specify another location.
* Use `--force` to override an existing configuration.

#### Logging

By default a log file `jupyter.log` will be written in the
current directory. An option `--logfile=XXX` argument can be
added to the argv argument of the server configuration file
(located at `$(jupyter --data)/kernels/raku/kernel.json`)
to change this.

#### Client configuration

The jupyter documentation describes the client configuration.
To start, you can generate files for the notebook or
console clients like this:

```
jupyter notebook --generate-config
jupyter console --generate-config

```

Some suggested configuration changes for the console client:

* set `kernel_is_complete_timeout` to a high number. Otherwise,
  if the kernel takes more than 1 second to respond, then from
  then on, the console client uses internal (non-Raku) heuristics
  to guess when a block of code is complete.
* set `highlighting_style` to `vim`. This avoids having dark blue
  on a black background in the console client.

### Running

Start the web UI with:

```
jupyter-notebook
Then select New -> Raku.

```

You can also use it in the console like this:

```
jupyter-console --kernel=raku

```

Or make a handy shell alias:

```
alias iraku='jupyter-console --kernel=raku'

```

## FEATURES

* **Autocompletion:** Typing `[tab]` in the client will send an autocomplete request. Possible autocompletions are:

  * methods: after a `.` the invocant will be evaluated to find methods
  * set operators: after a `(`, set operators (unicode and texas) will be shown (note the whitespace before the `(`)).
  * equality/inequality operators: after `=`, `<`, or `>`, related operators will be shown.
  * autocompleting `*` or `/` will give `×` or `÷` respectively.
  * autocompleting `**` or a superscript will give you superscripts (for typing exponents).
  * the word 'atomic' autocompletes to the [atomic operators](https://docs.raku.org/type/atomicint#Operators). (Use `atomic-` or `atom` to get the subroutines with their ASCII names).
  * a colon followed by a sequence of word characters will autocomplete
    to characters whose unicode name contains that string. Dashes are
    treated as spaces.
    e.g. :straw will find 🍓 ("STRAWBERRY") or 🥤 ("CUP WITH STRAW") and :smiling-face-with-smiling-eye will find 😊 ("SMILING FACE WITH SMILING EYES")
* **Keep output:** All cells are evaluated in item context. Outputs are then saved to an array
  named `$Out`. You can read from this directly or:

  * via the subroutine `Out` (e.g. `Out[3]`)
  * via an underscore and the output number (e.g. `_3`)
  * for the most recent output: via a plain underscore (`_`).
* **Magics:** There is some support for jupyter "magics". If the first line
  of a code cell starts with `#%` or `%%`, it may be interpreted as a directive
  by the kernel. See EXAMPLES. The following magics are supported:

  * `#% javascript`: interpret the cell as javascript; i.e. run it in the browser
  * `#% js`: return the output as javascript
  * `#% > js`: return stdout as javascript
  * `#% html`: return the output as html
  * `#% latex`: return the output as LaTeX. Use `latex(equation)` to wrap
    the output in `\begin{equation}` and `\end{equation}`. (Or replace
    "`equation`" with another string to use something else.)
  * `#% markdown` (or `md`): the output will be interpreted as markdown.
    Note that this is for generating markdown as the output of a cell, not for
    writing markdown, which can be done without magics. Also, this simply
    sends the data with the markdown mime-type, and the notebook does the rendering.
  * `#% > markdown` (or `md`): interpret stdout as markdown
  * `#% html > latex`: The above can be combined to render, for instance,
    the output cell as HTML, but stdout as LaTeX. The word before the `>`
    indicates the type of the output cell. The word after the `>` indictes
    the type of stdout.
  * `%% bash`: Interpret the cell as bash. stdout becomes the contents of
    the next cell. Behaves like Raku's built-in `shell`.
  * `%% run FILENAME`: Prepend the contents of FILENAME to the
    contents of the current cell (if any) before execution.
    Note this is different from the built-in `EVALFILE` in that
    if any lexical variables, subroutines, etc. are declared in FILENAME,
    they will become available in the notebook execution context.
  * `%% always [SUBCOMMAND] CODE`: SUBCOMMAND defaults to `prepend` but can be:

    * `prepend`: Prepend each cell by `CODE;\n`
    * `append`: Append `;\nCODE` after each command
    * `clear`: Clear all `always` registered actions
    * `show`: Show `always` registered actions
      You can combine it with another magic. For example:
      `%% always prepend %% run file.raku`
* **Comms:** Comms allow for asynchronous communication between a notebook
  and the kernel. For an example of using comms, see [this notebook](eg/comms.ipynb)

### Usage notes

* In the console, pressing return will execute the code in a cell. If you want
  a cell to span several lines, put a `\` at the end of the line, like so:

```
In [1]: 42
Out[1]: 42

In [2]: 42 +
Out[2]: Missing required term after infix

In [3]: 42 + \
      : 10 + \
      : 3 + \
      : 12
Out[3]: 67

```

Note that this is not the same as the raku 'unspace' -- a backslash followed
by a newline will be replaced with a newline before the code is executed. To
create an unspace at the end of the line, you can use two backslashes.

## DOCKER

[This blog post](https://sumankhanal.netlify.com/post/raku_notebook/) provides
a tutorial for running this kernel with Docker. [This one](https://sumdoc.wordpress.com/2018/01/04/using-perl-6-notebooks-in-binder/) describes using [Binder](https://mybinder.org/).

## EXAMPLES

The <eg/> directory of this repository has some
example notebooks:

* [Hello, world](eg/hello-world.ipynb).
* [Generating an SVG](eg/svg.ipynb).
* [Some unicodey math examples](http://nbviewer.jupyter.org/github/bduggan/p6-jupyter-kernel/blob/master/eg/math.ipynb)
* [magics](http://nbviewer.jupyter.org/github/bduggan/p6-jupyter-kernel/blob/master/eg/magics.ipynb)

## SEE ALSO

* [Docker image for Raku](https://hub.docker.com/r/sumankhanal/raku-notebook/)
* [iperl6kernel](https://github.com/timo/iperl6kernel)

## KNOWN ISSUES

* Newly declared methods might not be available in autocompletion unless SPESH is disabled (see tests in [this PR](https://github.com/bduggan/p6-jupyter-kernel/pull/11)).

## THANKS

Matt Oates

Suman Khanal

Timo Paulssen

Tinmarino

Anton Antonov

## FOOTNOTES

¹ Jupyter clients are user interfaces to interact with an interpreter kernel like `Jupyter::Kernel`.
Jupyter [Lab | Notebook | Console | QtConsole ] are the jupyter maintained clients.
More info in the [jupyter documentations site](https://jupyter.org/documentation).

² mybinder.org provides a way to instantly launch a Docker image and open a notebook.


## dist_github-peelle-Finance-CompoundInterest.md
# Finance::CompoundInterest

Subroutines for calculating compound interest.

2018 Update: While I still find the below documentation more fun to read that strictly facts documentation, I wanted to disclose I did make money, but no where near my my predictions.

# SYNOPSIS

I started a Lending Club account. While waiting on it to open I thought, What if I put in $5000, and assume I will make the minimum 6%? I can leave it alone and just come back after those three year notes done. What will that look like?

```
	use Finance::CompoundInterest;

	say compound_interest
			5000, 	# My initial payment, or principal
			.005, 	# Since it compounds monthly and that 6% really means yearly, it should be .06 / 12
			36, 	# Number of months we expect it to compound.
			3;	# At year 3 how will this look.

```

> 5075.56003652364

Well that's kinda cruddy. I can't retire to the Bahamas on that. I can't own a luxury yacht with a butler. Oh wait, for that matter I don't actually have $5K lying around. I live paycheck to paycheck like most everyone else I know.

What if I throw $150 a month into it, every month, for the next three years. How is it gonna look then?

```
	say compound_interest_with_payments
			150, 	# $150 every month.
			.005, 	# I wish that was .06 monthly
			36; 	# Number of months we expect it to compound.

```

> 5900.41574470244

Woohoo! I already out performed the first one! Using some multiplication and subtraction, I can see that I put in a little more money $5400, but I got way more interest out. $500 in interest. ChaChing!

What is this gonna look like if I can keep it up until I am 75? Lets see I'm 32 now, so I got another 43 years.

```
	say compound_interest_with_payments
			150, 		# $150 every month.
			.005, 		# .06 / 12
			43 * 12; 	# Number of months we expect it to compound.

```

> 363377.142315735

Now that is a chunk of change, and I only put in $1,800 a year.

But wait, I am a programmer. I am totally smarter than all those other guys that use their gut to choose stocks, loans, ponies, etc. I can use ~~spread sheets~~ databases, to comb through the data and make better choices.

Lending Club says their returns are between 6% and 10%. Lets assume I can hit that 10% mark. How many payment periods will it take me to get to the same dollar amount?

```
	say ciwp_payment_period
			363377, 	# Final amount.
			.0083, 		# We gotz skillz. 10% anually.
			150; 		# Monthly payments.

```

> 368.944160846191

Sweet, so I went from 516(43x12) contributions to 369(30.75x12). Sweet, almost 13 years saved! I knew learning ~~spread sheets~~ databases would pay off someday.

Hold on, not only am I a programmer, but I am a proper lazy Perl programmer. I don't wanna be working until I am 75, or 63! I wanna go live on that island, programming Perl, and sipping Mojitos sooner rather than later.

How much $$ do I need to put in to get this done in 20 years at age 52? Just over the hill, and out the door.

```
	say ciwp_payment_size
			363377, 	# Final amount.
			.0083, 		# Interest.
			20 * 12; 	# Number of months we want it to compound.

```

> 481.012899065815

About $481 a month? That's a bit rough, but doable. Island life is the life for me!

# DESCRIPTION

* **I am not a certified financial anything. Use at your own ruination.**

These modules were created to scratch my own itch. They do some simple financial calculations related to compound interest, so I can count my imaginary money.

# CAVEATS

* I am **not** a certified financial anything. Use at your own financial risk.
* My example calculations do not take into account any of that real world stuff, like taxes, fees, risk, giant spiders, or economic collapse.

# BUGS

* Did I mention that I am not a certified financial person? Double check me and submit patches. :).
* This uses the built in Rat data type. The Perl 6 tutorial said limited precision.

# TODO/HELP PLEASE

* To return the interest rate, given a final amount, payments, and periods.
* Add a formula where starting amount and periodic payments differ.
* Add a formula where payments more or less frequently added than the interest compounds.
* Add in other types of compound interest formulas.
* Make it more Perl6-ey

# AUTHOR

James (Jeremy) Carman [developer@peelle.org](mailto:developer@peelle.org)

# ACKNOWLEDGEMENTS

This README is shamelessly based on other Perl6 modules. So is my module layout, tests, and other not code files. Thank you for figuring this out first so I didn't have to.


## contains.md
contains

Combined from primary sources listed below.

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

See primary documentation
[in context](/type/Str#method_contains)
for **method contains**.

```raku
multi method contains(Str:D: Cool:D $needle, :i(:$ignorecase), :m(:$ignoremark) --> Bool:D)
multi method contains(Str:D: Str:D $needle, :i(:$ignorecase), :m(:$ignoremark) --> Bool:D)
multi method contains(Str:D: Regex:D $needle --> Bool:D)
multi method contains(Str:D: Cool:D $needle, Int(Cool:D) $pos, :i(:$ignorecase), :m(:$ignoremark) --> Bool:D)
multi method contains(Str:D: Str:D $needle, Int:D $pos, :i(:$ignorecase), :m(:$ignoremark) --> Bool:D)
multi method contains(Str:D: Regex:D $needle, Int:D $pos --> Bool:D)
multi method contains(Str:D: Regex:D $needle, Cool:D $pos --> Bool:D)
```

Given a `Str` invocant (known as the *haystack*) and a first argument (known as the `$needle`), it searches for the `$needle` in the *haystack* from the beginning of the string and returns `True` if `$needle` is found. If the optional parameter `$pos` is provided, then `contains` will search the *haystack* starting from `$pos` characters into the string.

```raku
say "Hello, World".contains('Hello');      # OUTPUT: «True␤»
say "Hello, World".contains('hello');      # OUTPUT: «False␤»
say "Hello, World".contains('Hello', 1);   # OUTPUT: «False␤»
say "Hello, World".contains(',');          # OUTPUT: «True␤»
say "Hello, World".contains(',', 3);       # OUTPUT: «True␤»
say "Hello, World".contains(',', 10);      # OUTPUT: «False␤»
```

In the first case, `contains` searches for the `'Hello'` string on the invocant right from the start of the invocant string and returns `True`. In the third case, the `'Hello'` string is not found since we have started looking from the second position (index 1) in `'Hello, World'`.

Since Rakudo version 2020.02, the `$needle` can also be a [`Regex`](/type/Regex) in which case the `contains` method quickly returns whether the regex matches the string at least once. No [`Match`](/type/Match) objects are created, so this is relatively fast.

```raku
say 'Hello, World'.contains(/\w <?before ','>/);    # OUTPUT: «True␤»
say 'Hello, World'.contains(/\w <?before ','>/, 5); # OUTPUT: «False␤»
```

Since Rakudo version 2020.02, if the optional named parameter `:ignorecase`, or `:i`, is specified, the search for `$needle` ignores the distinction between uppercase, lowercase, and titlecase letters.

```raku
say "Hello, World".contains("world");              # OUTPUT: «False␤»
say "Hello, World".contains("world", :ignorecase); # OUTPUT: «True␤»
```

Since Rakudo version 2020.02, if the optional named parameter `:ignoremark`, or `:m`, is specified, the search for `$needle` only considers base characters, and ignores additional marks such as combining accents.

```raku
say "abc".contains("ä");               # OUTPUT: «False␤»
say "abc".contains("ä", :ignoremark);  # OUTPUT: «True␤»
```

Note that because of how a [`List`](/type/List) or [`Array`](/type/Array) is [coerced](/type/List#method_Str) into a `Str`, the results may sometimes be surprising.

```raku
say <Hello, World>.contains('Hello');    # OUTPUT: «True␤»
say <Hello, World>.contains('Hello', 0); # OUTPUT: «True␤»
say <Hello, World>.contains('Hello', 1); # OUTPUT: «False␤»
```

See [traps](/language/traps#Lists_become_strings,_so_beware_.contains()).

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

See primary documentation
[in context](/type/Cool#method_contains)
for **method contains**.

```raku
method contains(Cool:D: |c)
```

Coerces the invocant to a [`Str`](/type/Str), and calls [`Str.contains`](/type/Str#method_contains) on it. Please refer to that version of the method for arguments and general syntax.

```raku
say 123.contains("2")# OUTPUT: «True␤»
```

Since [`Int`](/type/Int) is a subclass of `Cool`, `123` is coerced to a [`Str`](/type/Str) and then `contains` is called on it.

```raku
say (1,1, * + * … * > 250).contains(233)# OUTPUT: «True␤»
```

[`Seq`](/type/Seq)s are also subclasses of `Cool`, and they are stringified to a comma-separated form. In this case we are also using an [`Int`](/type/Int), which is going to be stringified also; `"233"` is included in that sequence, so it returns `True`. Please note that this sequence is not lazy; the stringification of lazy sequences does not include each and every one of their components for obvious reasons.


## redeclaration.md
class X::Redeclaration

Compilation error due to declaring an already declared symbol

```raku
class X::Redeclaration does X::Comp { }
```

Thrown when a symbol (variable, routine, type, parameter, ...) is redeclared. Note that redeclarations are generally fine in an inner scope, but if the redeclaration appears in the same scope as the original declaration, it usually indicates an error and is treated as one.

Examples

```raku
my $x; my $x;

```

dies with

｢text｣ without highlighting

```

```

===SORRY!===
Redeclaration of symbol $x

```

```

It works with routines too:

```raku
sub f() { }
sub f() { }

```

dies with

｢text｣ without highlighting

```

```

===SORRY!===
Redeclaration of routine f

```

```

But those are fine

```raku
my $x;
sub f() {
    my $x;          # not a redeclaration,
                    # because it's in an inner scope
    sub f() { };    # same
}

```

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

## [method symbol](#class_X::Redeclaration "go to top of document")[§](#method_symbol "direct link")

Returns the name of the symbol that was redeclared.

## [method what](#class_X::Redeclaration "go to top of document")[§](#method_what "direct link")

Returns the kind of symbol that was redeclared. Usually `symbol`, but can also be `routine`, `type` etc.

## [method postfix](#class_X::Redeclaration "go to top of document")[§](#method_postfix "direct link")

Returns a string that is attached to the end of the error message. It usually explains the particular problem in more detail, or suggests way to fix the problem.


## dist_zef-raku-community-modules-DBIish.md
# NAME

DBIish - a simple database interface for Raku

# SYNOPSIS

```
use v6;
use DBIish;

my $dbh = DBIish.connect("SQLite", :database<example-db.sqlite3>);

$dbh.execute(q:to/STATEMENT/);
    DROP TABLE IF EXISTS nom
    STATEMENT

$dbh.execute(q:to/STATEMENT/);
    CREATE TABLE nom (
        name        varchar(4),
        description varchar(30),
        quantity    int,
        price       numeric(5,2)
    )
    STATEMENT

$dbh.execute(q:to/STATEMENT/);
    INSERT INTO nom (name, description, quantity, price)
    VALUES ( 'BUBH', 'Hot beef burrito', 1, 4.95 )
    STATEMENT

my $sth = $dbh.prepare(q:to/STATEMENT/);
    INSERT INTO nom (name, description, quantity, price)
    VALUES ( ?, ?, ?, ? )
    STATEMENT

$sth.execute('TAFM', 'Mild fish taco', 1, 4.85);
$sth.execute('BEOM', 'Medium size orange juice', 2, 1.20);

# For one-off execution
$sth = $dbh.execute(q:to/STATEMENT/);
    SELECT name, description, quantity, price, quantity*price AS amount
    FROM nom
    STATEMENT
say $sth.rows; # 3

for $sth.allrows() -> $row {
    say $row[0];  # BUBH␤TAFM␤BEOM
}

$sth.dispose;

# For efficient multiple execution
$sth = $dbh.prepare('SELECT description FROM nom WHERE name = ?');
for <TAFM BEOM> -> $name {
    for $sth.execute($name).allrows(:array-of-hash) -> $row {
        say $row<description>;
    }
}

$dbh.dispose;

```

# DESCRIPTION

The DBIish project provides a simple database interface for Raku.

It's not a port of the Perl 5 DBI and does not intend to become one.
It is, however, a simple and useful database interface for Raku that works
now. It looks like a DBI, and it talks like a DBI (although it only offers
a subset of the functionality).

## Connecting to, and disconnecting from, a database

You obtain a `DataBaseHandler` by calling the static `DBIish.connect` method, passing
as the only positional argument the driver name followed by any required named arguments.

Those named arguments are driver specific, but commonly required ones are:
`database`, `user` and `password`.

For the different syntactic forms of
[named arguments](https://doc.perl6.org/language/functions#Arguments) see
the language documentation.

For example, for connect to a database 'hierarchy' on PostgreSQL, with the user in `$user`
and using the function `get-secret` to obtain you password, you can:

```
my $dbh = DBIish.connect('Pg', :database<hierarchy>, :$user, password => get-secret());

```

See ahead more examples.

To disconnect from a database and free the allocated resources you should call the
`dispose` method:

```
$dbh.dispose;

```

## Executing queries

### `execute`

For a single execution of a query you may use execute directly. This starts the query within the database and returns
a `StatementHandle` which will be used for [Retrieving Data](#retrieving-data).

```
$dbh.execute(q:to/SQL/);
  CREATE TABLE tab (
    id serial PRIMARY KEY
    col text
  );
  SQL

```

Errors occurring within the database for an SQL statement will typically throw an exception within Raku. The level of
detail within the exception object depends on the database driver.

```
$dbh.execute('CREATE TABLE failtab ( id );');

CATCH {
   when X::DBDish::DBError {
      say .message;
   }
}

```

In order to build a query dynamically without risk of SQL injection you need to use parameter binding. The `?`
will be replaced by an escaped copy of the parameter provided after the query.

```
my $value-id = 19;
$dbh.execute('INSERT INTO tab (id) VALUES (?)', $value-id);

my $value-text = q{Complex text ' value " with quotes};
$dbh.execute('INSERT INTO tab (id, col) VALUES (?, ?)', $value-id, $value-text);

# Undefined or Nil values will be converted to NULL by parameter binding.
my $value-nil;
$dbh.execute('INSERT INTO tab (id, col) VALUES (?, ?), $value-id, $value-nil);

```

Parameter binding should be used where-ever possible, even if the number of parameters is dynamic. In this case the
number of elements for IN is dynamic. The number of `?`'s is scaled to fit the list of items, and the list
is provided to execute as individual items.

```
my @value-list = 1 .. 6;
my $parameter-bind-marks = @value-list.map({'?'}).join(',')  # ?,?,?,?,?,?
my $query = 'SELECT id FROM tab WHERE id IN (%s)'.sprintf($parameter-bind-marks);
$dbh.execute($query, |@value-list);

```

All database drivers support basic Raku types like Int, Rat, Str, and Buf; some databases may support additional
complex types such as an Array of Str or Array of Int which may simplify the above example significantly. Please see
database specific documentation for additional type support.

### `prepare`

Execute performs a couple of steps on the client side, and often the database side as well, which may be cached
if a query is going to be executed several times. For simple queries, prepare() may increase performance by up to 50%

This is an inefficient example of running a query multiple times:

```
for 1 .. 100 -> $id {
  $dbh.execute('INSERT INTO tab (id) VALUES (?)', $id);
}

```

This example is more efficient as it uses prepare to decrease overhead on the client side; often on the
server-side too as the database may only need to parse the SQL once.

```
my $sth = $dbh.prepare('INSERT INTO tab (id) VALUES (?)');
for 1 .. 100 -> $id {
  $sth.execute($id);
}

```

## Retrieving data

DBIish provides the `row` and `allrows` methods to fetch values from a `StatementHandle` object returned by execute.
These functions provide you typed values; for example an int4 field in the database will be provided as an Int
scalar in Raku.

### `row`

`row` take the `hash` adverb if you want to have the values in a Hash form instead of a plain Array

Example:

```
my $sth = $dbh.execute('SELECT id, col FROM tab WHERE id = ?', $value-id);

my @values = $sth.row();
my %values = $sth.row(:hash);

```

### `allrows`

`allrows` lazily returns all the rows as a list of arrays.
If you want to fetch the values in a hash form, use one of the two adverbs `array-of-hash`
or `hash-of-array`

Example:

```
my $sth = $dbh.execute('SELECT id, col FROM tab');

my @data = $sth.allrows(); # [[1, 'val1'], [3, 'val2']]
my @data = $sth.allrows(:array-of-hash); # [ ( id => 1, col => 'val1'), ( id => 3, col => 'val2') ]
my %data = $sth.allrows(:hash-of-array); # id => [1, 3], col => ['val1', 'val2']

for $sth.allrows(:array-of-hash) -> $row {
  say $row<id>;  # 1␤3
}

# Or as a shorter example:
for $dbh.execute('SELECT id, col FROM tab').allrows(:array-of-hash) -> $row {
   say $row<id>  # 1␤3
}

```

### `dispose`

After you have fetched all data using the statement handle, you can free its memory immediately using `dispose`.

```
$sth.dispose;

```

### `server-version`

`server-version` returns a `Version` object for the version of the server you are connected to. Not all drivers support
this function (some may not connect to a server at all) so it's best to wrap in a `can`.

```
my Version $version = $dbh.server-version() if $dbh.can('server-version');

```

## Statement Exceptions

All exceptions for a query result are thrown as or inherit `X::DBDish::DBError`. Additional functionality may
be provided by the database driver.

* `driver-name`

  Database Driver name for the connection
* `native-message`

  Unmodified message received from the database server.
* `code`

  Int return code from the local client library for the call; typically -1. This is not an SQL state.
* `why`

  A Str indicating why the exception was thrown. Typically 'Error'.
* `message`

  Human friendly and more informative version of the database message.
* `is-temporary`

  A Boolean flag which when true indicates that the transaction may succeed if retried. Connectivity issues,
  serialization issues and other temporary items may set this as True.

## Advanced Query Building

In general you should use the `?` parameter for substitution whenever possible. The database driver
will ensure values are properly escaped prior to insertion into the database. However, if you need to create
a query string by hand then you can use `quote` to help prevent an SQL injection attack from being successful.

### `quote($literal)` and `quote($identifier, :as-id)`

Using parameter substitution is preferred:

```
my $val = 'literal';
$dbh.execute('INSERT INTO tab VALUES (?)', $val);

```

However, if you must build the query directly you can:

```
my $val = 'literal';
my $query = 'INSERT INTO tab VALUES (%s)'.sprintf( $dbh.quote($val) );
$dbh.execute($query);

```

To build a query with a dynamic identifier:

```
# Notice that C<?> is still used for the value being inserted; it is still recommended where possible.
my $id = 'table';
my $val = 'literal';
my $query = 'INSERT INTO %s VALUES (?)'.sprintf( $dbh.quote($id, :as-id) );
$dbh.execute($query, $val);

```

# INSTALLATION

```
$ zef install DBIish

```

# DBDish CLASSES

Some DBDish drivers install together with DBIish.pm6 and are maintained as a single project.

Search the Raku ecosystem for additional [DBDish](https://modules.raku.org/search/?q=dbdish) drivers such
as [ODBC](https://github.com/salortiz/DBDish-ODBC).

Currently the following backends are included:

## Pg (PostgreSQL)

Supports basic CRUD operations and prepared statements with placeholders

```
my $dbh = DBIish.connect('Pg', :host<db01.yourdomain.com>, :port(5432),
        :database<blerg>, :user<myuser>, password => get-secret());

```

Pg supports the following named arguments:
`host`, `hostaddr`, `port`, `database` (or its alias `dbname`), `user`, `password`,
`connect-timeout`, `client-encoding`, `options`, `application-name`, `keepalives`,
`keepalives-idle`, `keepalives-interval`, `sslmode`, `requiressl`, `sslcert`, `sslkey`,
`sslrootcert`, `sslcrl`, `requirepeer`, `krbsrvname`, `gsslib`, and `service`.

See your [PostgreSQL documentation](https://www.postgresql.org/docs/current/libpq-envars.html) for details.

### Parameter Substitution

In addition to the `?` style of parameter substitution supported by all drivers, PostgreSQL also supports numbered
parameter. The advantage is that a numbered parameter may be reused

```
$dbh.execute('INSERT INTO tab VALUES ($1, $2, $2 - $1)', $var1, $var2);

```

This is equivalent to the below statement except the subtraction operation is performed by PostgreSQL:

```
$dbh.execute('INSERT INTO tab VALUES (?, ?, ?)', $var1, $var2, $var2 - $var1);

```

### pg arrays

Pg arrays are supported for both writing via execute and retrieval via `row/allrows`.
You will get the properly typed array according to the field type.

Passing an array to `execute` is now implemented. But you can also use the
`pg-array-str` method on your Pg StatementHandle to convert an Array to a
string Pg can understand:

```
# Insert an array via an execute statement
my $sth = $dbh.execute('INSERT INTO tab (array_column) VALUES ($1);', @data);

# Prepare an insertion of an array field
my $sth = $dbh.prepare('INSERT INTO tab (array_column) VALUES ($1);');
$sth.execute(@data1);   # or $sth.execute($sth.pg-array-str(@data1));
$sth.execute(@data2);

# Retrieve the array values back again.
for $dbh.execute('SELECT array_column FROM tab').allrows() -> $row {
   my @array-column = $row[0];
}

# Check if "value" is in the dataset. This is similar to an IN statement.
my $sth = $dbh.prepare('SELECT * FROM tab WHERE value = ANY($1)');
$sth.execute(@data);

# If a datatype is needed you can cast the placeholder with the PostgreSQL datatype.
my $sth = $dbh.prepare('SELECT * FROM tab WHERE value = ANY($1::_cidr)');
$sth.execute(['127.0.0.1', '10.0.0.1']);

```

### `pg-consume-input`

Consume available input from the server, buffering the read data if there is any.
This is only necessary if you are planning on calling `pg-notifies` without having
requested input by other means (such as an `execute`.)

### `pg-notifies`

```
$ret = $dbh.pg-notifies;

```

Looks for any asynchronous notifications received and returns a pg-notify object that looks like this

```
    class pg-notify {
        has Str                           $.relname; # Channel Name
        has int32                         $.be_pid; # Backend pid
        has Str                           $.extra; # Payload
    }

```

or nothing if there are no pending notifications.

In order to receive the notifications you should execute the PostgreSQL command "LISTEN"
prior to calling `pg-notifies` the first time; if you have not executed any other
commands in the meantime you will also need to execute `pg-consume-input` first.

For example:

```
$dbh.execute("LISTEN foo");

loop {
    $dbh.pg-consume-input
    if $dbh.pg-notifies -> $not {
        say $not;
    }
}

```

The payload is optional and will always be an empty string for PostgreSQL servers less than version 9.0.

### `ping`

Test to see if the connection is still considered live.

```
$dbh.ping

```

### Statement Exceptions

Exceptions for a query result are thrown as `X::DBDish::DBError::Pg` objects (inherits `X::DBDish::DBError`)
and have the following additional attributes (described with a `PG_DIAG_*` source name) as provided by the
[PostgreSQL client library libpq](https://www.postgresql.org/docs/current/libpq-exec.html):

* `message`

  `PG_DIAG_MESSAGE_PRIMARY` -
  The primary human-readable error message (typically one line). Always present.
* `message-detail`

  `PG_DIAG_MESSAGE_DETAIL` -
  Detail: an optional secondary error message carrying more detail about the problem. Might run to multiple lines.
* `message-hint`

  `PG_DIAG_MESSAGE_HINT` -
  Hint: an optional suggestion what to do about the problem. This is intended to differ from detail in that it offers advice (potentially inappropriate) rather than hard facts. Might run to multiple lines.
* `context`

  `PG_DIAG_CONTEXT` -
  An indication of the context in which the error occurred. Presently this includes a call stack traceback of active procedural language functions and internally-generated queries. The trace is one entry per line, most recent first.
* `type`

  `PG_DIAG_SEVERITY_NONLOCALIZED` -
  The severity; the field contents are ERROR, FATAL, or PANIC (in an error message), or WARNING, NOTICE, DEBUG, INFO, or LOG (in a notice message). This is identical to the PG\_DIAG\_SEVERITY field except that the contents are never localized. This is present only in reports generated by PostgreSQL versions 9.6 and later.
* `type-localized`

  `PG_DIAG_SEVERITY` -
  The severity; the field contents are ERROR, FATAL, or PANIC (in an error message), or WARNING, NOTICE, DEBUG, INFO, or LOG (in a notice message), or a localized translation of one of these. Always present.
* `sqlstate`

  `PG_DIAG_SQLSTATE` -
  The SQLSTATE code for the error. The SQLSTATE code identifies the type of error that has occurred; it can be used by front-end applications to perform specific operations (such as error handling) in response to a particular database error. For a list of the possible SQLSTATE codes, see Appendix A. This field is not localizable, and is always present.
* `statement`

  Statement provided to prepare() or execute()
* `statement-name`

  Statement Name provided to prepare() or created internally
* `statement-position`

  `PG_DIAG_STATEMENT_POSITION` -
  A string containing a decimal integer indicating an error cursor position as an index into the original statement string. The first character has index 1, and positions are measured in characters not bytes.
* `internal-position`

  `PG_DIAG_INTERNAL_POSITION` -
  This is defined the same as the `PG_DIAG_STATEMENT_POSITION` field, but it is used when the cursor position refers to an internally generated command rather than the one submitted by the client. The `PG_DIAG_INTERNAL_QUERY` field will always appear when this field appears.
* `internal-query`

  `PG_DIAG_INTERNAL_QUERY` -
  The text of a failed internally-generated command. This could be, for example, a SQL query issued by a PL/pgSQL function.
* `dbname`

  Database Name from libpq `pg-db()`
* `host`

  Host from libpq `pg-host()`
* `user`

  User from libpq `pg-user()`
* `port`

  Port from libpq `pg-port()`
* `schema`

  `PG_DIAG_SCHEMA_NAME` -
  If the error was associated with a specific database object, the name of the schema containing that object, if any.
* `table`

  `PG_DIAG_TABLE_NAME` -
  If the error was associated with a specific table, the name of the table. (Refer to the schema name field for the name of the table's schema.)
* `column`

  `PG_DIAG_COLUMN_NAME` -
  If the error was associated with a specific table column, the name of the column. (Refer to the schema and table name fields to identify the table.)
* `datatype`

  `PG_DIAG_DATATYPE_NAME` -
  If the error was associated with a specific data type, the name of the data type. (Refer to the schema name field for the name of the data type's schema.)
* `constraint`

  `PG_DIAG_CONSTRAINT_NAME` -
  If the error was associated with a specific constraint, the name of the constraint. Refer to fields listed above for the associated table or domain. (For this purpose, indexes are treated as constraints, even if they weren't created with constraint syntax.)
* `source-file`

  `PG_DIAG_SOURCE_FILE` -
  The file name of the source-code location where the error was reported.
* `source-line`

  `PG_DIAG_SOURCE_LINE` -
  The line number of the source-code location where the error was reported.
* `source-function`

  `PG_DIAG_SOURCE_FUNCTION` -
  The name of the source-code function reporting the error.

Please see the [PostgreSQL documentation](https://www.postgresql.org/docs/current/static/libpq-exec.html#LIBPQ-PQRESULTERRORFIELD)
for additional information.

A special `is-temporary()` method returns True if an immediate retry of the full transaction should be attempted:

It is set to true when the [SQLState](https://www.postgresql.org/docs/current/static/errcodes-appendix.html)
is any of the following codes:

* SQLState Class 08XXX

  All connection exceptions (possible temporary network issues)
* SQLState 40001

  serialization\_failure - Two or more transactions conflicted in a manner which may succeed if executed later.
* SQLState 40P01

  deadlock\_detected - Two or more transactions had locking conflicts resulting in a deadlock and this transaction being rolled back.
* SQLState Class 57XXX

  Operator Intervention (early/forced connection termination).
* SQLState 72000

  snapshot\_too\_old - The transaction took too long to execute. It may succeed during a quieter period.

### `pg-socket`

```
    my Int $socket = $dbh.pg-socket;

```

Returns the file description number of the connection socket to the server.

## SQLite

Supports basic CRUD operations and prepared statements with placeholders

```
my $dbh = DBIish.connect('SQLite', :database<thefile>);

```

The `:database` parameter can be an absolute file path as well (or even an
`IO::Path` object):

```
my $dbh = DBIish.connect('SQLite', database => '/path/to/sqlite.db' );

```

If the SQLite library was compiled to be threadsafe (which is usually the
case), then it is possible to use SQLite from multiple threads. This can be
introspected:

```
say DBIish.install-driver('SQLite').threadsafe;

```

SQLite does support using one connection object concurrently, however other
databases may not; if portability is a concern, then only use a particular
connection object from one thread at a time (and so have multiple connection
objects).

When using a SQLite database concurrently (from multiple threads, or even
multiple processes), operations may not be able to happen immediately due to
the database being locked. DBIish sets a default timeout of 10000 milliseconds;
this can be changed by passing the `busy-timeout` option to `connect`.

```
my $dbh = DBIish.connect('SQLite', :database<thefile>, :60000busy-timeout);

```

Passing a value less than or equal to zero will disable the timeout, resulting
in any operation that cannot take place immediately producing a database
locked error.

### Function rows()

Since SQLite may retrieve records in the background, the `rows()` method will not be accurate
until all records have been retrieved from the database. A warning is thrown when this may be the case.

This warning message may be suppressed using a `CONTROL` phaser:

```
CONTROL {
    when CX::Warn {
        when .message.starts-with('SQLite rows()') { .resume }
        default { .rethrow }
    }
}

```

Making `rows()` accurate for all calls would require the driver pre-retrieving and caching
all records with a large performance and memory penalty, then providing the records as requested.

For best performance you are recommended to use:

```
while my $row = $sth.row {
    # Do something with all records as retrieved
}

if my $row = $sth.row {
    # Do something with a single record
}

```

## MySQL

Supports basic CRUD operations and prepared statements with placeholders

```
my $dbh = DBIish.connect('mysql', :host<db02.yourdomain.com>, :port(3306),
        :database<blerg>, :user<myuser>, :$password);

# Or via socket:
my $dbh = DBIish.connect('mysql', :socket<mysql.sock>,
        :database<blerg>, :user<myuser>, :$password);

```

MySQL driver supports the following named arguments:
`connection-timeout`, `read-timeout`, `write-timeout`

See your [MySQL documentation](https://dev.mysql.com/doc/c-api/5.6/en/mysql-options.html) for details.

Since MariaDB uses the same wire protocol as MySQL, the `mysql` backend
also works for MariaDB.

### Statement Exceptions

Exceptions for a query result are thrown as `X::DBDish::DBError::mysql` objects (inherits `X::DBDish::DBError`)
and have the following additional attributes as provided by the MySQL client libraries.

* `message`

  `mysql_error` -
  The primary human-readable error message (typically one line). Always present.
* `code`

  `mysql_errno` -
  Integer code. Always present.
* `sqlstate`

  `mysql_sqlstate` -
  The SQLSTATE code for the error. The SQLSTATE code identifies the type of error that has occurred; it can be used by front-end applications to perform specific operations (such as error handling) in response to a particular database error. For a list of the possible SQLSTATE codes, see Appendix A. This field is not localizable, and is always present.

### Required Client-C libraries

DBDish::mysql by default searches for 'mysql' (libmysql.ddl) on Windows, and
'mariadb' (libmariadb.so.xx where xx in 0 .. 4) then
'mysqlclient' (libmysqlclient.so.xx where xx in 16..21) on POSIX systems.

Remember that Windows uses `PATH` to locate the library. On POSIX,
unversionized `*.so` files installed by "dev" packages aren't needed nor used,
you need the run-time versionized library.

On POSIX you can use the `$DBIISH_MYSQL_LIB` environment variable to request another
client library to be searched and loaded.

Example using the unadorned name:

```
DBIISH_MYSQL_LIB=mariadb rakudo t/25-mysql-common.t

```

Using the absolute path in uninstalled DBIish:

```
DBIISH_MYSQL_LIB=/lib64/libmariadb.so.3 rakudo -t lib t/25-mysql-common.t

```

With MariaBD-Embedded:

```
DBIISH_MYSQL_LIB=mariadbd rakudo -I lib t/01-basic.t

```

### `insert-id`

Returns the AUTO\_INCREMENT value of the most recently inserted record.

```
my $sth = $dbh.execute( 'INSERT INTO tab (description) VALUES (?)', $description );

my $id = $sth.insert-id;

# or
my $id = $dbh.insert-id;

```

## Oracle

Supports basic CRUD operations and prepared statements with placeholders

```
my $dbh = DBIish.connect('Oracle', database => 'XE', :user<sysadm>, :password('secret'));

```

By default connections to Oracle will apply this session alteration in an attempt to
ensure the formatted "TIMESTAMP WITH TIME ZONE" field string will be compatible with DateTime
and returned to the user as DateTime.new($ts\_str).

```
ALTER SESSION SET nls_timestamp_tz_format = 'YYYY-MM-DD"T"HH24:MI:SS.FFTZR'

```

WARNING: This alteration does not include support for these field types. Also until now these
types would have thrown an exception as an unknown TYPE.

```
TIMESTAMP
TIMESTAMP WITH LOCAL TIME ZONE

```

WARNING: Any form of TIMESTAMP(0) will produce a string not compatible with DateTime
due to the ".FF" and the lack of fractional seconds to fulfill it.

You can choose to use this session alteration in an attempt to simplify the use of
ISO-8601 timestamps; strictly speaking, formatted as "YYYY-MM-DDTHH:MI:SSZ"; no offsets
etc shown but Oracle outo converts to GMT(00:00).
This session management forces all client sessions to UTC and sets formats for all DATE
and TIMESTAMP types; it does however sacrifice any fraction seconds TIMESTAMPS may be
storing. It also insures TIMSTAMP(0) works without causing DateTime.new($ts) to fault.

```
DBIish.connect( 'Oracle', :alter-session-iso8601, ... );

ALTER SESSION SET time_zone               = '-00:00'
ALTER SESSION SET nls_date_format         = 'YYYY-MM-DD"T"HH24:MI:SS"Z"'
ALTER SESSION SET nls_timestamp_format    = 'YYYY-MM-DD"T"HH24:MI:SS"Z"'
ALTER SESSION SET nls_timestamp_tz_format = 'YYYY-MM-DD"T"HH24:MI:SS"Z"'

```

WARNING: Preexisting databases that used time zones other than UTC/GMT/-00:00 may need
to convert current timestamps to -00:00 to ensure timestamp correctness. It will depend
on the type of TIMESTAMP used and how Oracle was configured.

NOTICE: By default DBIish lower-cases FIELD names. This is noticed when data is returned
as a hash.

For consumer purists that desire DBIish to leave session management alone, the above
behaviors can be disabled using these options in the connect method. These options will
allow DBIish to most closely behave like Perl5's DBI defaults. These are my personal
favorite settings.

```
:no-alter-session      # don't alter session
:no-datetime-container # return the date/timestamps as stings
:no-lc-field-names     # return field names unaltered

```

## Threads

I have a long history of using Threads, Oracle and Perl5. I have yet to read any
useful online notes regarding successful usage of Raku, threads & DBIish; I thought
I'd share recent experience.

Since early 2021 I've successfully implemented my Raku solution for using as
many as Eight(8) threads all connected to Oracle performing simultaneous Reads and
writes. As with Perl-5 the number one requirement is to ensure each thread
creates is own connection handle with Oracle. In case you're interested; its
implemented as a layer on top of DBIish that when .enable(N) is used determines
the number of worker threads; each capable to handling reads or writes. The
primary application delegates writes to the workers and reads are asynchronously
delivered where requested. This solution allows the application to stay focused on
it's primary purpose while dedicated writers handle the DB updates.

Regards,
ancient-wizard

# TESTING

The `DBIish::CommonTesting` module, now with over 100 tests, provides a common unit
testing that allows a driver developer to test its driver capabilities and the
minimum expected compatibility.

Set environment variable `DBIISH_WRITE_TEST=YES` to run tests which may leave permanent state changes in the database.

# SEE ALSO

The Raku Pod in the doc:DBIish module and examples in the [examples](https://github.com/raku-community-modules/DBIish/tree/master/examples) directory.

This README and the documentation of the DBIish and the DBDish modules
are in the Pod6 format. It can be extracted by running

```
rakudo --doc <filename>

```

Or, if [Pod::To::HTML](https://metacpan.org/pod/Pod%3A%3ATo%3A%3AHTML) is installed,

```
rakudo --doc=html <filename>

```

Additional modules of interest may include:

* [DBIish::Transaction](https://modules.raku.org/dist/DBIish::Transaction:cpan:RBT)

  A wrapper for managing transactions, including automatic retry for temporary failures.
* [DBIish::Pool](https://modules.raku.org/dist/DBIish::Pool:cpan:RBT)

  Connection reuse for DBIish to reduce loads on high-volume or heavily encrypted database sessions.

## HISTORY

DBIish is based on Martin Berends' [MiniDBI](https://github.com/mberends/MiniDBI) project, but unlike MiniDBI, DBDish
aims to provide an interface that takes advantage of Raku idioms.

There is/was an intention to integrate with the [DBDI project](http://github.com/timbunce/DBDI)
once it has sufficient functionality.

So, while it is indirectly inspired by [Perl 5 DBI](https://metacpan.org/pod/DBI), there are also many differences.

# COPYRIGHT

Written by Moritz Lenz, based on the MiniDBI code by Martin Berends.

See the [CREDITS](https://github.com/raku-community-modules/DBIish/blob/master/CREDITS) file for a list of all contributors.

# LICENSE

Copyright © 2009-2020, the DBIish contributors
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice,
  this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
  notice, this list of conditions and the following disclaimer in the
  documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.


## dist_zef-raku-community-modules-Geo-Region.md
[![Actions Status](https://github.com/raku-community-modules/Geo-Region/actions/workflows/linux.yml/badge.svg)](https://github.com/raku-community-modules/Geo-Region/actions) [![Actions Status](https://github.com/raku-community-modules/Geo-Region/actions/workflows/macos.yml/badge.svg)](https://github.com/raku-community-modules/Geo-Region/actions) [![Actions Status](https://github.com/raku-community-modules/Geo-Region/actions/workflows/windows.yml/badge.svg)](https://github.com/raku-community-modules/Geo-Region/actions)

# NAME

Geo::Region - Geographical regions and groupings using UN M.49 and CLDR data

# VERSION

This document describes Geo::Region for Raku, built with Unicode CLDR v26.

# SYNOPSIS

```
use Geo::Region;
use Geo::Region::Enum;

$amer = Geo::Region.new(include => Region::Americas);

$emea = Geo::Region.new(
    include => (Region::Europe, Region::WesternAsia, Region::Africa)
);

$apac = Geo::Region.new(
    include => (Region::Asia, Region::Oceania),
    exclude => Region::WesternAsia,
);

if $amer.contains($country) {
    # country is in the Americas (US, MX, BR, etc.)
}
elsif $emea.contains($country) {
    # country is in Europe, the Middle East, and Africa (FR, SA, ZW, etc.)
}
elsif $apac.contains($country) {
    # country is in Asia-Pacific (JP, TH, AU, etc.)
}

```

# DESCRIPTION

The `Geo::Region` class is used to create geographical regions and groupings of subregions and countries. Default regional groupings are provided using the [Unicode CLDR v26 Territory Containment](https://unicode.org/cldr/charts/26/supplemental/territory_containment_un_m_49.html) data, which is an extension of the United Nations [UN M.49 (Rev.3)](https://unstats.un.org/unsd/methods/m49/m49regin.htm) standard.

## Regions

Regions and subregions are represented with UN M.49 region codes, such as **419** for Latin America and **035** for Southeast Asia. Either the official format using a three-digit `0`-padded string like `'035'` or an integer like `35` may be used with this class. Note when using the `0`-padded format that it must be quoted as a string so as not to be treated as on octal literal.

The CLDR also adds two additional two-letter region codes which are supported: **EU** for the European Union and **QO** for Outlying Oceania. These region codes are all available as enumerations in Geo::Region::Enum.

## Countries

Countries and territories are represented with ISO 3166-1 alpha-2 country codes, such as **JP** for Japan and **AQ** for Antarctica, and are case insensitive. Unlike with region codes, the three-digit forms of country codes are not currently supported, nor are three-letter codes. The deprecated code **UK** for the United Kingdom is supported as an alias of the official code **GB**.

## Constructor

The `new` class method is used to construct a Geo::Region object along with the `include` argument and optional `exclude` argument.

### include

Accepts either a single region code or an array reference of region or country codes to be included in the resulting custom region.

```
# countries in the European Union (EU)
Geo::Region.new(include => Region::EuropeanUnion);

# countries in Asia (142) plus Russia (RU)
Geo::Region.new(include => (Region::Asia, Country::Russia));

```

### exclude

Accepts values in the same format as `include`. This can be used to exclude countries or subregions from a region.

```
# countries in Europe (150) which are not in the European Union (EU)
Geo::Region.new(
  include => Region::Europe,
  exclude => Region::EuropeanUnion,
);

```

## Methods

### contains

Given a country or region code, determines if the region represented by the Geo::Region instance contains it.

```
if $region.contains($country) {

```

### is-within

Given a region code, determines if all the countries and regions represented by the Geo::Region instance are within it.

```
if $subregion.is-within($region) {

```

### countries

Returns a list of country codes of the countries within the region represented by the Geo::Region instance.

```
for $region.countries -> $country {

```

# SEE ALSO

* [Unicode CLDR: UN M.49 Territory Containment](http://unicode.org/cldr/charts/26/supplemental/territory_containment_un_m_49.html)
* [United Nations: UN M.49 Standard Country, Area, & Region Codes](http://unstats.un.org/unsd/methods/m49/m49regin.htm)

# AUTHOR

Nova Patch

# COPYRIGHT AND LICENSE

Copyright 2014 - 2018 Nova Patch

Copyright 2024 Raku Community

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


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

# NAME

**Mi6::Helper** - Creates a base repository for a new Raku module managed by **App::Mi6**

# SYNOPSIS

This module installs a Raku executable named `mi6-helper` which is designed for the following operation:

```
$ mi6-helper new=Foo::Bar

```

That creates a new module named `Foo::Bar` in the current directory (or a specified directory if the option `dir=/path` is used). The new module is then ready to be enhanced and managed by app `mi6` to easily build build documentation, run tests, and release new versions.

Run `mi6-helper` without arguments to see its help screen showing its options:

```
Usage: mi6-helper <mode> [options...]

Modes:
  new=X - Creates a new module (named 'X') in the current directory
          by executing 'mi6', then modifying files and adding new
          files in the new repository to add the benefits produced
          by this module. NOTE: The program will abort if directory
          'X' exists.

Options:
  dir=P - Selects directory 'P' as the parent directory for the
          operations (default is '.', the current directory, i.e.,
          '$*CWD').

  force - Allows the program to continue without a hidden file
          and bypass the prompt/response dialog.

```

# DESCRIPTION

The installed program, `mi6-helper`, enables easy creation of a template for a new Raku module repository for management by `App::Mi6`. It does that by first executing `mi6` to create the base module and then modifying the result to add new capabilities. (Note the directory for module 'X::Y-Z' will be 'P/X-Y-Z'. See details in the README.)

Note when `mi6` creates its files, it shows text in the `README.md` file as 'Foo::Bar - blah blah blah'. That can be changed to a brief summary statement by creating a hidden file in the parent directory with the same name as the new diretory. For example, new module `Foo::Bar` will be created in a new directory `Foo-Bar`. You can create hidden file `.Foo-Bar` and put any text desired in it. The author typically puts in text something like this:

```
Provides routines to check existing module base repositories for errors.

```

If the hidden file does not exist, the user will be asked if he or she wishes to continue without it. If the answer is `yes`, then the program will continue and the "blah blah blah" will remain. If the answer is `no`, the program will terminate. (Note the program will wait indefinitely for a response, so you should use option "force" if you are testing or otherwise executing the program apart from a terminal inteface.)

## Post repository creation

The changes and additions in your new repository include:

1. Modifying the `dist.ini` file for the enhancements
2. User choice of the brief descriptive text (recommended, but not required)
3. `README.md` file source placed in a new `docs/README.rakudoc` file so you can update your docs using Rakupod instead of Markdown (convert to updated Markdown by running `mi6 build`).
4. Using three separate OS tests in `.github/workflows`: shows results of each in the now auto-generated `README.md` file
5. Publishing in the **Zef** Raku module ecosystem (now standard with the current `mi6`)

**NOTE**: If one of the non-Linux OS tests fail during remote testing on Github, you can eliminate that test by doing the following two steps (for example, remove the `windows` test which is the most likely to fail):

* Move the `windows.yml` file out of the `.github/workflows/` directory (the author uses a subdir named `dev` to hold such things).
* Put a semicolon in the `dist.ini` file to comment out the line naming the `windows.yml` file.

## Modified files for the repository

In addition to those changes, the README is converted to a Rakudoc file in a new `./docs/` directory. Then the `dist.ini` file is modified to create the `README.md` file in the base directory. Both files are placed under `git` control.

See [RepoChanges](RepoChanges.md) for full details of each changed line from the original created by `App::Mi6`.

See published module `Foo::Bar` for an example of a module created by `mi6-helper`.

## Special installation requirements

The user must install and have an account with `fez` to use this module to create a new module repository. To do that:

```
zef install fez
fez register

```

## Define the branch `git origin`

The author uses and recommends **GitHub** for the `git origin` for your new module's repository.

A short list of steps to define such for our example 'Foo::Bar':

1. Define a new repo on GitHub named 'Foo-Bar' (note no '::' separator)
2. On your computer, use the shell terminal to run these commands (for Linux or MacOS):

   $ cd /path/to/some-parent-dir
   $ mi6-helper new=Foo::Bar

The new repository should be created with a branch name per your personal settings for the Git default branch name (I use 'main' here). This is the output:

```
Getting description text from hidden file '.Foo-Bar'
[main (root-commit) 30a8b25] 'initial'
 12 files changed, 431 insertions(+)
 create mode 100644 .github/workflows/linux.yml
 create mode 100644 .github/workflows/macos.yml
 create mode 100644 .github/workflows/windows.yml
 create mode 100644 .gitignore
 create mode 100644 Changes
 create mode 100644 LICENSE
 create mode 100644 META6.json
 create mode 100644 README.md
 create mode 100644 dist.ini
 create mode 100644 docs/README.rakudoc
 create mode 100644 lib/Foo/Bar.rakumod
 create mode 100644 t/0-load-test.rakutest
Using directory '/path/to/some-parent-dir'
  as the working directory.
Exit after 'new' mode run. See new module repo 'Foo-Bar'
in parent dir '/path/to/some-parent-dir'.

```

At this point, execute the following commands to define the origin and push the new branch to the repo awaiting it on GitHub:

```
# GitHub shows this choice: ...or push an existing repository from the command line...
# We follow those instructions with our fresh 'Foo::Bar' repo:
$ git remote add origin git@github.com:user/Foo-Bar.git
$ git branch -M main
$ git push -u origin main

```

## See also

A new, in-work [App::DistroLint](https://github.com/tbrowder/App-DistroLint) by the author.

# AUTHOR

Tom Browder [tbrowder@acm.org](mailto:tbrowder@acm.org)

# CREDITS

The very useful Raku modules used herein:

* [`App::Mi6`](https://github.com/skaji/mi6) by **zef:skaji**
* [`File::Directory::Tree`](https://github.com/labster/p6-file-directory-tree) by **github:labster**
* [`File::Temp`](https://github.com/raku-community-modules/File-Temp) by **zef:rbt**
* [`Proc::Easier`](https://github.com/sdondley/Proc-Easier) by **zef:sdondley**
* [`File::Find`](https://github.com/raku-community-modules/File-Find) by **zef:raku-community-modules**
* [`MacOS::NativeLib`](https://github.com/lizmat/MacOS-NativeLib) by **zef:lizmat**

# COPYRIGHT AND LICENSE

© 2020-2025 Tom Browder

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


## dist_github-ALANVF-LLVM.md
# Raku-LLVM

Raku bindings for the LLVM that go beyond the C API (like it uses raku stuff).

Make sure that you have LLVM 7 installed (for now at least).

Todo:

* Add more examples.
* Add helper constructs/functions (such as an if/else function for `Builder`s).
* Add documentation (might use POD6 or pages idk).
* Add (at least a few) tests.


## tap.md
tap

Combined from primary sources listed below.

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

See primary documentation
[in context](/type/Supply#method_tap)
for **method tap**.

```raku
method tap(Supply:D: &emit = -> $ { },
        :&done = -> {},
        :&quit = -> $ex { $ex.throw },
        :&tap = -> $ {} )

```

Creates a new tap (a kind of subscription if you will), in addition to all existing taps. The first positional argument is a piece of code that will be called when a new value becomes available through the `emit` call.

The `&done` callback can be called in a number of cases: if a supply block is being tapped, when a `done` routine is reached; if a supply block is being tapped, it will be automatically triggered if the supply block reaches the end; if the `done` method is called on the parent [`Supplier`](/type/Supplier) (in the case of a supply block, if there are multiple Suppliers referenced by `whenever`, they must all have their `done` method invoked for this to trigger the `&done` callback of the tap as the block will then reach its end).

The `&quit` callback is called if the tap is on a supply block which exits with an error. It is also called if the `quit` method is invoked on the parent [`Supplier`](/type/Supplier) (in the case of a supply block any one [`Supplier`](/type/Supplier) quitting with an uncaught exception will call the `&quit` callback as the block will exit with an error). The error is passed as a parameter to the callback.

The `&tap` callback is called once the [`Tap`](/type/Tap) object is created, which is passed as a parameter to the callback. The callback is called ahead of `emit`/`done`/`quit`, providing a reliable way to get the [`Tap`](/type/Tap) object. One case where this is useful is when the `Supply` begins emitting values synchronously, since the call to `.tap` won't return the [`Tap`](/type/Tap) object until it is done emitting, preventing it from being stopped if needed.

Method `tap` returns an object of type [`Tap`](/type/Tap), on which you can call the `close` method to cancel the subscription.

```raku
my $s = Supply.from-list(0 .. 5);
my $t = $s.tap(-> $v { say $v }, done => { say "no more ticks" });
```

Produces:

｢text｣ without highlighting

```

```

0
1
2
3
4
5
no more ticks

```

```


## dist_cpan-TITSUKI-Algorithm-ZhangShasha.md
[![Build Status](https://travis-ci.org/titsuki/raku-Algorithm-ZhangShasha.svg?branch=master)](https://travis-ci.org/titsuki/raku-Algorithm-ZhangShasha)

# NAME

Algorithm::ZhangShasha - Tree edit distance between trees

# SYNOPSIS

```
use Algorithm::ZhangShasha;

my class SimpleHelper does Algorithm::ZhangShasha::Helpable[Algorithm::ZhangShasha::Node] {
    method delete-cost(Algorithm::ZhangShasha::Node $this --> Int) {
        1;
    }

    method insert-cost(Algorithm::ZhangShasha::Node $another --> Int) {
        1;
    }

    method replace-cost(Algorithm::ZhangShasha::Node $this, Algorithm::ZhangShasha::Node $another --> Int) {
        $another.content eq $this.content ?? 0 !! 1;
    }

    method children(Algorithm::ZhangShasha::Node $node) {
        $node.children
    }
}

my constant $ZN = 'Algorithm::ZhangShasha::Node';

my $root1 = ::($ZN).new(:content("f"))\
                   .add-child(::($ZN).new(:content("d"))\
                                     .add-child(::($ZN).new(:content("a")))\
                                     .add-child(::($ZN).new(:content("c"))\
                                                       .add-child(::($ZN).new(:content("b")))\
                                               )\
                             )\
                   .add-child(::($ZN).new(:content("e")));

my $root2 = ::($ZN).new(:content("f"))\
                   .add-child(::($ZN).new(:content("c"))\
                                     .add-child(::($ZN).new(:content("d"))\
                                                       .add-child(::($ZN).new(:content("a")))\
                                                       .add-child(::($ZN).new(:content("b")))\
                                               )\
                             )\
                   .add-child(::($ZN).new(:content("e")));

my Algorithm::ZhangShasha::Tree[Algorithm::ZhangShasha::Node] $tree1 .= new(:root($root1), :helper(SimpleHelper.new));
my Algorithm::ZhangShasha::Tree[Algorithm::ZhangShasha::Node] $tree2 .= new(:root($root2), :helper(SimpleHelper.new));

say $tree1.tree-distance($tree2).key; # 2
say $tree1.tree-distance($tree2).value; # ({op => KEEP, pair => 1 => 1} {op => KEEP, pair => 2 => 2} {op => DELETE, pair => 3 => 2} {op => KEEP, pair => 4 => 3} {op => INSERT, pair => 4 => 4} {op => KEEP, pair => 5 => 5} {op => KEEP, pair => 6 => 6})

```

# DESCRIPTION

Algorithm::ZhangShasha is an implementation for efficiently computing tree edit distance between trees.

## METHODS of Algorithm::ZhangShasha::Tree

### BUILD

Defined as:

```
submethod BUILD(NodeT :$!root!, Algorithm::ZhangShasha::Helpable :$!helper!)

```

Creates an `Algorithm::ZhangShasha::Tree` instance.

* `$!root` is the root node of the tree
* `$!helper` is the helper class that implements four methods: `delete-cost`, `insert-cost`, `replace-cost`, `children`. If you want to combine 3rd-party node representation (e.g., `DOM::Tiny`), you should define a custom helper. (See `t/01-basic.t`. It implements an exmple for `DOM::Tiny`.)

### size

Defined as:

```
method size(--> Int)

```

Returns the size of the tree.

### tree-distance

Defined as:

```
method tree-distance(Algorithm::ZhangShasha::Tree $another --> Pair)

```

Returns a `Pair` instance that has the optimal edit distance and the corresponding operations (e.g., DELETE(3,2)) between the two trees. Where `.key` has the distance and `.value` has the operations.

# AUTHOR

Itsuki Toyota [titsuki@cpan.org](mailto:titsuki@cpan.org)

# COPYRIGHT AND LICENSE

Copyright 2020 Itsuki Toyota

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

This algorithm is from

* [0] Zhang, Kaizhong, and Dennis Shasha. "Simple fast algorithms for the editing distance between trees and related problems." SIAM journal on computing 18.6 (1989): 1245-1262.


## dist_zef-jforget-Date-Calendar-Persian.md
# NAME

Date::Calendar::Persian - Conversions from / to the Persian calendar

# SYNOPSIS

Converting a Gregorian date (e.g. 16th February 2021) into Persian

```
use Date::Calendar::Persian;
my Date $dt-greg;
my Date::Calendar::Persian $dt-persian;

$dt-greg    .= new(2021, 2, 16);
$dt-persian .= new-from-date($dt-greg);

say $dt-persian;
# --> 1399-11-28
say $dt-persian.strftime("%A %d %B %Y");
# --> Se shanbe 28 Bahman 1399

```

Converting a Persian date (e.g. 1 Farvardin 1400) into Gregorian

```
use Date::Calendar::Persian;
my Date::Calendar::Persian $dt-persian;
my Date $dt-greg;

$dt-persian .= new(year => 1400, month => 1, day => 1);
$dt-greg   = $dt-persian.to-date;

say $dt-greg;
# --> 2021-03-21

```

# DESCRIPTION

Date::Calendar::Persian is a class representing dates in the Persian
calendar. It allows you to convert a Persian date into Gregorian or
into other implemented calendars, and it allows you to convert dates
from Gregorian or from other calendars into Persian.

The Date::Calendar::Persian class gives the arithmetic version of the
Persian calendar. The astronomic Persian calendar is partially
implemented in Date::Calendar::Persian::Astronomical, included in this
distribution.

# INSTALLATION

```
zef install Date::Calendar::Persian

```

or

```
git clone https://github.com/jforget/raku-Date-Calendar-Persian.git
cd raku-Date-Calendar-Persian
zef install .

```

# AUTHOR

Jean Forget

# COPYRIGHT AND LICENSE

Copyright (c) 2021, 2024 Jean Forget, all rights reserved.

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


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

# NAME

CBOR::Simple - Simple codec for the CBOR serialization format

# SYNOPSIS

```
use CBOR::Simple;

# Encode a Raku value to CBOR, or vice-versa
my $cbor = cbor-encode($value);
my $val1 = cbor-decode($cbor);               # Fails if more data past first decoded value
my $val2 = cbor-decode($cbor, my $pos = 0);  # Updates $pos after decoding first value

# By default, cbor-decode() marks partially corrupt parsed structures with
# Failure nodes at the point of corruption
my $bad  = cbor-decode(buf8.new(0x81 xx 3));  # [[[Failure]]]

# Callers can instead force throwing exceptions on any error
my $*CBOR_SIMPLE_FATAL_ERRORS = True;
my $bad  = cbor-decode(buf8.new(0x81 xx 3));  # BOOM!

# Decode CBOR into diagnostic text, used for checking encodings and complex structures
my $diag = cbor-diagnostic($cbor);

# Force the encoder to tag a value with a particular tag number
my $tagged = CBOR::Simple::Tagged.new(:$tag-number, :$value);
my $cbor   = cbor-encode($tagged);

```

# DESCRIPTION

`CBOR::Simple` is an easy-to-use implementation of the core functionality of the [CBOR serialization format](https://cbor.io/), implementing the standard as of [RFC 8949](https://tools.ietf.org/html/rfc8949), plus a collection of common tag extensions as described below in [TAG IMPLEMENTATION STATUS](#tag-implementation-status).

## PERFORMANCE

`CBOR::Simple` is one of the fastest data structure serialization codecs available for Raku. It is comparable in round-trip speed to `JSON::Fast` for data structures that are the most JSON-friendly. For all other cases tested, `CBOR::Simple` produces smaller, higher fidelity encodings, faster. For more detail, and comparison with other Raku serialization codecs, see [serializer-perf](https://github.com/japhb/serializer-perf).

## NYI

Currently known NOT to work:

* Any tag marked '✘' (valid but not yet supported) or 'D' (deprecated spec) in the ENCODE or DECODE column of the Tag Status Details table below, or any tag not explicitly listed therein, will be treated as an opaque tagged value rather than treated as a native type.
* Packed arrays of 128-bit floats (num128); these are not supported in Rakudo yet.
* Encoding *finite* 16-bit floats (num16); encoding 16-bit NaN and ±Inf, as well as decoding any num16 all work. This is a performance tradeoff rather than a technical limitation; detecting whether a finite num32 can be shrunk to 16 bits without losing information is costly and rarely results in space savings except in trivial cases (e.g. Nums containing only small integers).

## TAG CONTENT STRICTNESS

When encoding, `CBOR::Simple` makes every attempt to encode tagged content strictly within the tag standards as written, always producing spec-compliant encoded values.

When decoding, `CBOR::Simple` will often slightly relax the allowed content types in tagged content, especially when later tag proposals made no change other than to extend the allowed content types and allocate a new tag number for that. In the extension case `CBOR::Simple` is likely to allow both the old and new tag to accept the same content domain when decoding.

For example, when encoding `CBOR::Simple` will always encode `Instant` or `DateTime` as a CBOR epoch-based date/time (tag 1), using standard integer or floating point content data. But when *decoding*, `CBOR::Simple` will accept any content that decodes properly as a Raku `Real` value -- and in particular will handle a CBOR Rational (tag 30) as another valid content type.

## DATE, DATETIME, INSTANT

Raku's builtin time handling is richer than the default CBOR data model (though certain tag extensions improve this), so the following mappings apply:

* Encoding

  * `Instant` and `DateTime` are both written as tag 1 (epoch-based date/time) with integer (if lossless) or floating point content.
  * Other `Dateish` are written as tag 100 (RFC 8943 days since 1970-01-01).
* Decoding

  * Tag 0 (date/time string) is parsed as a `DateTime`.
  * Tag 1 (epoch-based date/time) is parsed via `Instant.from-posix()`, and handles any Real type in the tag content.
  * Tag 100 (days since 1970-01-01) is parsed via `Date.new-from-daycount()`.
  * Tag 1004 (date string) is parsed as a `Date`.

## UNDEFINED VALUES

* CBOR's `null` is translated as `Any` in Raku.
* CBOR's `undefined` is translated as `Mu` in Raku.
* A real `Nil` in an array (which must be *bound*, not assigned) is encoded as a CBOR Absent tag (31). Absent values will be recognized on decode as well, but since array contents are *assigned* into their parent array during decoding, a `Nil` in an array will be translated to `Any` by Raku's array assignment semantics.

## OTHER SPECIAL CASES

* To mark a substructure for lazy decoding (treating it as an opaque `Blob` until explicitly decoded), use the tagged value idiom in the SYNOPSIS with `:tag-number(24)` (encoded CBOR value) or `:tag-number(63)` (encoded CBOR Sequence).
* CBOR strings claiming to be longer than `2⁶³-1` are treated as malformed.
* Bigfloats and decimal fractions (tags 4, 5, 264, 265) with very large exponents may result in numeric overflow when decoded.
* Keys for Associative types are sorted using Raku's internal `sort` method rather than the RFC 8949 default sort, because the latter is much slower.
* `cbor-diagnostic()` always adds encoding indicators for float values.

## TAG IMPLEMENTATION STATUS

Note that unrecognized tags will decode to their contents wrapped with a `CBOR::Simple::Tagged` object that records its `tag-number`; check marks in the details table indicate conversion to/from an appropriate native Raku type rather than this default behavior.

Tag Status Overview: Native Raku Types

| GROUP | SUPPORT | NOTES |
| --- | --- | --- |
| Core | Good | Core RFC 8949 CBOR data model and syntax |
| Collections | Good | Sets, maps with only object or only string keys |
| Graph | NONE | Cyclic, indirected, and self-referential structures |
| Numbers | Good | Rational/BigInt/BigFloat support except non-finite triplets |
| Packed Arrays | Partial | Packed num32/64, [u]int\* arrays full; num16 is read-only |
| Special Arrays | NONE | Explicit multi-dim/homogenous arrays |
| Tag Fallbacks | Good | Round tripping of unknown tagged content |
| Date/Time | Partial | All but tagged time (tags 1001-1003) supported |

Tag Status Overview: Specialty Types

| GROUP | SUPPORT | NOTES |
| --- | --- | --- |
| Encodings | NONE | baseN, MIME, YANG, BER, non-UTF-8 strings |
| Geo | NONE | Geographic coordinates and shapes |
| Identifiers | NONE | URI, IRI, UUID, IPLD CID, general identifiers |
| Networking | NONE | IPv4/IPv6 addresses, subnets, and masks |
| Security | NONE | COSE and CWT |
| Specialty | NONE | IoT data, Openswan, PlatformV, DOTS, ERIS, RAINS |
| String Hints | NONE | JSON conversions, language tags, regex |

Tag Status Details

| SPEC | TAGS | ENCODE | DECODE | NOTES |
| --- | --- | --- | --- | --- |
| RFC 8949 | 0 | → | ✓ | DateTime strings → Encoded as tag 1 |
| RFC 8949 | 1 | ✓ | ✓ | DateTime/Instant |
| RFC 8949 | 2,3 | ✓ | ✓ | (Big) Int |
| RFC 8949 | 4,5 | → | ✓ | Big fractions → Encoded as tag 30 |
| unassigned | 6-15 |  |  |  |
| COSE | 16-18 | ✘ | ✘ | MAC/Signatures |
| unassigned | 19-20 |  |  |  |
| RFC 8949 | 21-23 | ✘ | ✘ | Expected JSON conversion to baseN |
| RFC 8949 | 24 | T | ✓ | Encoded CBOR data item |
| [Lehmann] | 25 | ✘ | ✘ | String backrefs |
| [Lehmann] | 26,27 | ✘ | ✘ | General serialized objects |
| [Lehmann] | 28,29 | ✘ | ✘ | Shareable referenced values |
| [Occil] | 30 | ✓ | ✓ | Rational numbers |
| [Vaarala] | 31 | ✓ | \* | Absent values |
| RFC 8949 | 32-34 | ✘ | ✘ | URIs and base64 encoding |
| RFC 7094 | 35 | D | D | PCRE/ECMA 262 regex (DEPRECATED) |
| RFC 8949 | 36 | ✘ | ✘ | Text-based MIME message |
| [Clemente] | 37 | ✘ | ✘ | Binary UUID |
| [Occil] | 38 | ✘ | ✘ | Language-tagged string |
| [Clemente] | 39 | ✘ | ✘ | Identifier semantics |
| RFC 8746 | 40 | ✘ | ✘ | Row-major multidim array |
| RFC 8746 | 41 | ✘ | ✘ | Homogenous array |
| [Mische] | 42 | ✘ | ✘ | IPLD content identifier |
| [YANG] | 43-47 | ✘ | ✘ | YANG datatypes |
| unassigned | 48-51 |  |  |  |
| draft | 52 | D | D | IPv4 address/network (DEPRECATED) |
| unassigned | 53 |  |  |  |
| draft | 54 | D | D | IPv6 address/network (DEPRECATED) |
| unassigned | 55-60 |  |  |  |
| RFC 8392 | 61 | ✘ | ✘ | CBOR Web Token (CWT) |
| unassigned | 62 |  |  |  |
| [Bormann] | 63 | T | ✓ | Encoded CBOR Sequence |
| RFC 8746 | 64-79 | ✓ | ✓ | Packed int arrays |
| RFC 8746 | 80-87 | \* | ✓ | Packed num arrays (except 128-bit) |
| unassigned | 88-95 |  |  |  |
| COSE | 96-98 | ✘ | ✘ | Encryption/MAC/Signatures |
| unassigned | 99 |  |  |  |
| RFC 8943 | 100 | ✓ | ✓ | Date |
| unassigned | 101-102 |  |  |  |
| [Vidovic] | 103 | ✘ | ✘ | Geo coords |
| [Clarke] | 104 | ✘ | ✘ | Geo coords ref system WKT/EPSG |
| unassigned | 105-109 |  |  |  |
| RFC 9090 | 110-112 | ✘ | ✘ | BER-encoded object ID |
| unassigned | 113-119 |  |  |  |
| [Vidovic] | 120 | ✘ | ✘ | IoT data point |
| unassigned | 121-255 |  |  |  |
| [Lehmann] | 256 | ✘ | ✘ | String backrefs (see tag 25) |
| [Occil] | 257 | ✘ | ✘ | Binary MIME message |
| [Napoli] | 258 | ✓ | ✓ | Set |
| [Holloway] | 259 | T | ✓ | Map with object keys |
| [Raju] | 260-261 | ✘ | ✘ | IPv4/IPv6/MAC address/network |
| [Raju] | 262-263 | ✘ | ✘ | Embedded JSON/hex strings |
| [Occil] | 264-265 | → | \* | Extended fractions -> Encoded as tag 30 |
| [Occil] | 266-267 | ✘ | ✘ | IRI/IRI reference |
| [Occil] | 268-270 | ✘✘ | ✘✘ | Triplet non-finite numerics |
| RFC 9132 | 271 | ✘✘ | ✘✘ | DDoS Open Threat Signaling (DOTS) |
| [Vaarala] | 272-274 | ✘ | ✘ | Non-UTF-8 strings |
| [Cormier] | 275 | T | ✓ | Map with only string keys |
| [ERIS] | 276 | ✘ | ✘ | ERIS binary read capability |
| [Meins] | 277-278 | ✘ | ✘ | Geo area shape/velocity |
| unassigned | 279-1000 |  |  |  |
| [Bormann] | 1001-1003 | ✘ | ✘ | Extended time representations |
| RFC 8943 | 1004 | → | ✓ | → Encoded as tag 100 |
| unassigned | 1005-1039 |  |  |  |
| RFC 8746 | 1040 | ✘ | ✘ | Column-major multidim array |
| unassigned | 1041-22097 |  |  |  |
| [Lehmann] | 22098 | ✘ | ✘ | Hint for additional indirection |
| unassigned | 22099-25440 |  |  |  |
| [Broadwell] | 25441 | ✓ | ✓ | Capture: reference implementation |
| unassigned | 25442-49999 |  |  |  |
| [Tongzhou] | 50000-50011 | ✘✘ | ✘✘ | PlatformV |
| unassigned | 50012-55798 |  |  |  |
| RFC 8949 | 55799 | ✓ | ✓ | Self-described CBOR |
| [Richardson] | 55800 | ✓ | ✓ | Self-described CBOR Sequence |
| unassigned | 55801-65534 |  |  |  |
| invalid | 65535 |  | ✓ | Invalid tag detected |
| unassigned | 65536-15309735 |  |  |  |
| [Trammell] | 15309736 | ✘✘ | ✘✘ | RAINS message |
| unassigned | 15309737-1330664269 |  |  |  |
| [Hussain] | 1330664270 | ✘✘ | ✘✘ | CBOR-encoded Openswan config file |
| unassigned | 1330664271-4294967294 |  |  |  |
| invalid | 4294967295 |  | ✓ | Invalid tag detected |
| unassigned | ... |  |  |  |
| invalid | 18446744073709551615 |  | ✓ | Invalid tag detected |

Tag Table Symbol Key

| SYMBOL | MEANING |
| --- | --- |
| ✓ | Fully supported |
| \* | Supported, but see notes above |
| T | Encoding supported by explicitly tagging contents |
| → | Raku values will be encoded using a different tag |
| D | Deprecated and unsupported tag spec; may eventually be decodable |
| ✘ | Not yet implemented |
| ✘! | Not yet implemented, but already requested |
| ✘? | Not yet implemented, but may be easy to add |
| ✘✘ | Probably won't be implemented in CBOR::Simple |

# AUTHOR

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

# COPYRIGHT AND LICENSE

Copyright 2021,2025 Geoffrey Broadwell

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


## dist_zef-masukomi-XDG-GuaranteedResources.md
# NAME

XDG::GuaranteedResources - Guarantees that a resource is present in the expected XDG Base Directory directory

# SYNOPSIS

First, you need to implement a class that can get resources from within your package. I suggest you copy this, and change the class name. Alas, this is not something that another package like this one can provide.

```
use XDG::GuaranteedResources::AbstractResourcer;

unit class My::Resourcer does XDG::GuaranteedResources::AbstractResourcer;

# for XDG::GuaranteedResources::AbstractResourcer
method fetch-resource(::?CLASS:U:){%?RESOURCES;}

```

Once you've got that, you can just pass it in as the 2nd param to either of the provided methods, or assign it to a variable and pass that in.

```
use XDG::GuaranteedResources;
# pass it the relative path to a file under your resources directory
# path must be listed in the resources array of your META6.json
guarantee-resource("config/my_app/app_config.toml", My::Resourcer);

# assigning your resourcer to a variable is fine.
my $resourcer = My::Resourcer;
# if you have multiple to guarantee you pass a list to the plural form.
guarantee-resources(<config/my_app/app_config.toml data/my_app/cool_database.db>, $resourcer);

```

# DESCRIPTION

Many tools expect a config file, sqlite database, or similar to be present. We store these in the resources listed in `META6.json`, and need to test if they exist and copy them over from `resources` if not.

`XDG::GuaranteedResources` handles this common operation.

For example:

Let's assume your script uses a pre-prepared sqlite db that you store under resources. Store it under `resources/data/my_app/my_database.db`, then when your script boots up you can call `guarantee-resource("data/my_app/my_database.db");`. If that file already exists under `%*ENV<XDG_CONFIG_HOME>/my_app/my_database.db` nothing will happen. If it isn't found there, a fresh copy will be placed there from the one you referenced in `resources`.

Note that `my_app` should be the directory name your apps files should be stored under. For example, a config file for [clu](https://github.com/masukomi/clu) would be stored under `~/.config/clu/` after install. So, you would store it under `resources/config/clu/` in your package.

Resources that should be copied to `XDG_CONFIG_HOME` should be stored under `resources/config/my_app`

Resources that should be copied to `XDG_DATA_HOME` should be stored under `resources/data/my_app`

Subdirectories are fine. E.g. `resources/data/my_app/subdir/my_db.db`

⚠ Currently only works on Unix (Linux, BSD, macOS, etc.) systems.

# AUTHOR

Kay Rhodes a.k.a masukomi ([masukom@masukomi.org](mailto:masukom@masukomi.org))

# COPYRIGHT AND LICENSE

Copyright 2022

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

### multi sub guarantee-resource

```
multi sub guarantee-resource(
    Str $resource_path,
    $resourcer
) returns Str

```

Guarantees a resource is present & provides the path it can be found at.

### sub guarantee-resources

```
sub guarantee-resources(
    @resource_paths,
    $resourcer
) returns Array

```

Guarantees a list of resources are present. Returns the paths they can be found at.


## community.md
Community

Information about the people working on and using Raku

# [Overview](#Community "go to top of document")[§](#Overview "direct link")

"Perl 5 was my rewrite of Perl. I want Perl 6 to be the community's rewrite of Perl and of the community." - Larry Wall (circa 2000)

"I am in favor of this change [a community driven renaming from Perl 6 to Raku], because it reflects an ancient wisdom: 'No one sews a patch of unshrunk cloth on an old garment, for the patch will pull away from the garment, making the tear worse. Neither do people pour new wine into old wineskins. If they do, the skins will burst; the wine will run out and the wineskins will be ruined. No, they pour new wine into new wineskins, and both are preserved.'" - Larry Wall ([2019](https://github.com/Raku/problem-solving/pull/89#pullrequestreview-300789072))

# [The Raku community](#Community "go to top of document")[§](#The_Raku_community "direct link")

## [Online communities](#Community "go to top of document")[§](#Online_communities "direct link")

[IRC](/language/glossary#IRC) communication has played an integral role in the Raku community for more than a decade. There are various channels for Raku-related activities on `libera.chat`. There are several [bots](/language/glossary#Bot) to make IRC activity more convenient and fun. You can read about IRC content [here](https://raku.org/community/irc/) in greater details.

[The Raku Discord server](https://discord.gg/VzYpdQ6) serves a similar purpose. Thanks to the bridges written by fellow Raku members, it integrates well with the main IRC channels.

[StackOverflow](https://stackoverflow.com/questions/tagged/raku) is also a great resource for asking questions and helping others with their Raku problems and challenges.

More resources can be found in the [raku.org community page](https://raku.org/community/).

## [Offline communities](#Community "go to top of document")[§](#Offline_communities "direct link")

Raku is also a common topic at [Perl conferences](https://www.perl.org/events.html) and [Perl Monger meetings](https://www.pm.org/). If you prefer in-person meetings, these are warmly recommended!

## [Other resources](#Community "go to top of document")[§](#Other_resources "direct link")

[Camelia](https://raku.org/), the multi-color butterfly with P 6 in her wings, is the symbol of this diverse and welcoming community.

# [Rakudo Weekly](#Community "go to top of document")[§](#Rakudo_Weekly "direct link")

Elizabeth Mattijsen usually posts in [the "Rakudo Weekly" blog](https://rakudoweekly.blog/), a summary of Raku posts, tweets, comments and other interesting tidbits. If you want a single resource to know what is going on in the Raku community now, this is your best resource.

Historical articles (pre name change) can be found archived on [the "Perl 6 Weekly" blog](https://p6weekly.wordpress.com/).

# [Raku Advent calendar](#Community "go to top of document")[§](#Raku_Advent_calendar "direct link")

The Raku community publishes every December an [Advent Calendar](https://raku-advent.blog/), with Raku tutorials every day until Christmas. Previous calendars (pre name change) are [still available](https://perl6advent.wordpress.com/) and relevant.

Organization and assignment of days is done through the different Raku channels and the [Raku/advent](https://github.com/Raku/advent) repository. If you want to participate, its organization starts by the end of October, so check out the channels above to keep up to date.


## dist_cpan-ASHER-Operator-Listcat.md
# Operator-Listcat

A module that adds operators and methods for merging lists
in a clean way. See:

## [Perl 6 Needs a List Concatenation Op](http://ajs.github.io/tools/perl-6-list-concat-op/)

From that article:

There are three things here:

* The infix operator `listcat` that works as `<a b c> listcat <x y z>` and
  returns `<a b c x y z>` but without flattening any further than one level.
* The Unicode alias `⊕` for listcat that evokes the Python (among a small
  number of other languages') convention of using
  `+` for this purpose without actually muddying the type waters.
* A modification to `List` that adds the `sling` method that performs
  a `listcat` between the `List` object that it's called on and its
  arguments, returning the unified list.

## Licence

This is free software.

Please see the [LICENCE](LICENSE.md) for the details.


## dist_zef-tbrowder-SantaClaus-Utils.md
[![Actions Status](https://github.com/tbrowder/SantaClaus-Utils/workflows/test/badge.svg)](https://github.com/tbrowder/SantaClaus-Utils/actions)

# NAME

**SantaClaus::Utils** - Provides Raku software tools for Santa Claus and his Elves

# SYNOPSIS

```
use SantaClaus::Utils;

add-entry;     # adds a journal entry template to the
               # user's '$HOME/journal' text file
check-journal; # checks the journal file for correct syntax

```

# DESCRIPTION

The Raku module **SantaClaus::Utils** is used by Santa's staff to create and manage individual task journal entries. It also provide tools to manage as the entire collection of task journals for all Santa's helpers to provide status reports and other reports for Santa and his staff.

# AUTHOR

Tom Browder [tbrowder@acm.org](mailto:tbrowder@acm.org)

# COPYRIGHT AND LICENSE

Copyright 2021 Tom Browder

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


## dist_zef-raku-community-modules-Text-LDIF.md
[![Actions Status](https://github.com/raku-community-modules/Text-LDIF/actions/workflows/linux.yml/badge.svg)](https://github.com/raku-community-modules/Text-LDIF/actions) [![Actions Status](https://github.com/raku-community-modules/Text-LDIF/actions/workflows/macos.yml/badge.svg)](https://github.com/raku-community-modules/Text-LDIF/actions) [![Actions Status](https://github.com/raku-community-modules/Text-LDIF/actions/workflows/windows.yml/badge.svg)](https://github.com/raku-community-modules/Text-LDIF/actions)

# NAME

Text::LDIF - Pure Raku LDIF file parser

# SYNOPSIS

```
use Text::LDIF;

my $ldif-content = slurp @*ARGS[0];

my $ldif = Text::LDIF.new;

my $result = $ldif.parse($ldif-content);

if $result {
	for $result<entries><> -> $entry {
        say "dn -> ", $entry<dn>;
        my %attrs = $entry<attrs>;
        for %attrs.kv -> $attr, $value {
            say "\t$attr ->\t$_" for @$value;
            # some further processing for cases of attributes with options,
            # base64, file urls, etc
        }
		say "-" x 40;
	}
}
else {
    say "Parsing error";
}

```

# DESCRIPTION

`Text::LDIF` is a Raku module for parsing LDIF files according to RFC 2849.

For the end-user, the `Text::LDIF` class is available to use. It has a `parse` method that accepts a `Str` that contains text of LDIF file and returns a structure that describes the file.

# OUTPUT STRUCTURE

LDIF can contain either a description of a number of LDAP entries or a set of changes made to directory entries. In case of LDAP entries description, the parsing result looks this way:

```
{
  version => 1, # exact number is parsed from file
  entries => [
    {
      dn => $dn-string,
      attrs => {
        # For a simple value, just string
        attr1 => 'foo',
        # For an attribute with many values, a list
        attr2 => ['foo', 'baz', 'bar'],
        # For base64 string a Pair
        attr3 => base64 => 'V2hhdCBh...',
        attr-with-opts => { # OPTIONS
          '' => 'value-of-just-attr-with-opts',
          lang-ja => 'value of attr-with-opts:lang-ja',
          lang-ja,phonetic => 'value of attr-with-opts:lang-ja:phonetic',
        },
        fileattr => file => 'file://foo.jpg', # eternal file url
        ...
      }
    },
        ...
  ]
}

```

A parsing result of modifications looks this way:

```
{
  version => 1,
  changes => [
    { # ADD
      dn => $dn-string,
      change => add => {
        attr1 => ...
      },
      controls => []
    },
    { # DELETE
      dn => $dn-string,
      change => 'delete',
      controls => []
    },
    { # MODDN
      dn => $dn-string,
      change => moddn => {
        delete-on-rdn => True, # Bool value
        newrdn => 'foo=baz',
        superior => Any # if not specified
      },
      controls => []
    },
    { # MODIFY
      dn => $dn-string,
      change => modify => [
        add => attr1 => 'attr1-value',
        delete => attr2,
        replace => attr3 => ['old-value', 'new-value'],
        ...
      ],
      controls => [ # CONTROLS
        {
          ldap-oid => '1.2.840...',
          criticality => True, # Bool value
          value => 'new-foo-value'
        },
        ...
      ]
    },
    ...
  ]
}

```

# AUTHOR

* Sylwester Lunski
* Alexander Kiryuhin

# COPYRIGHT AND LICENSE

Copyright 2016 - 2021 Alexander Kiryuhin

Copyright 2024 Raku Community

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


## shift.md
shift

Combined from primary sources listed below.

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

See primary documentation
[in context](/type/independent-routines#sub_shift)
for **sub shift**.

```raku
multi shift(@a) is raw
```

Calls method `shift` on the [`Positional`](/type/Positional) argument. That method, on a mutable collection that actually implements it (such as an [`Array`](/routine/shift#(Array)_method_shift) or a [`Buf`](/type/Buf#method_shift)), is supposed to remove and return the first element, or return a [`Failure`](/type/Failure) if the collection is empty.

Example:

```raku
say shift [1,2]; # OUTPUT: «1␤»
```

```raku
my @a of Int = [1];
say shift @a; # OUTPUT: «1␤»
say shift @a; # ERROR: «Cannot shift from an empty Array[Int]␤»

```

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

See primary documentation
[in context](/type/Array#method_shift)
for **method shift**.

```raku
method shift(Array:D:) is nodal
```

Removes and returns the first item from the array. Fails if the array is empty.

Example:

```raku
my @foo = <a b>;
say @foo.shift;             # OUTPUT: «a␤»
say @foo.shift;             # OUTPUT: «b␤»
say @foo.shift;
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::Cannot::Empty: Cannot shift from an empty Array␤»
```

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

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

```raku
method shift()
```

Removes and returns the first element of the buffer.

```raku
my $bú = Buf.new( 1, 1, 2, 3, 5 );
say $bú.shift(); # OUTPUT: «1␤»
say $bú.raku;    # OUTPUT: «Buf.new(1,2,3,5)␤»
```