## dist_cpan-HANENKAMP-Auth-SASL.md
# NAME

Auth::SASL - Simple Authentication Security Layer

# SYNOPSIS

```
use Auth::SASL;
use Base64;

# naïve ESMTP handler...
my $smtp = IO::Socket::INET.new(:host<localhost>, :port(25));
$smtp.print("EHLO localhost\n");
my ($more, %properties);
repeat {
    if $smtp.get ~~ /^ (\d\d\d)(<[-\ ]>)(.*) $/ {
        my ($code, $more, $props) = ("$0", $1 eq "-", "$2");
        if $props ~~ /(<[-\w]>+) >> <[=\ \t]>* (<-[\n]>*)/ {
            %properties{ "$0" } = "$1";
        }
    }
    else {
        die "error occurred while initiating SMTP connection";
    }
} while $more;

my $mechanisms = %properties<AUTH>;

my $sasl = Auth::SASL.new;
$sasl.begin-session(
    data => %(
        user     => 'zostay',
        pass     => 'secret',
        authname => 'zostay',
    ),
);

my ($response-code, $challenge);
MECHANISM: for $sasl.attempt-mechanisms($mechanisms, :service<smtp>, :host<localhost>) {
    $smtp.print("AUTH $_.mechanism\n");
    ($response-code, $challenge) = $smtp.get.split(' ', 2);
    next MECHANISM unless $response-code eq '334';

    $challenge = '';
    repeat {
        $smtp.print(encode-base64(.step($challenge), :str) ~ "\n");
        ($response-code, $challenge) = $smtp.get.split(' ', 2);
        next MECHANISM unless $response-code ~~ /^ 2 | 3 /;
    } until .is-complete;

    last MECHANISM if $response-code eq '235';

    CATCH {
        when X::Auth::SASL {
            $smtp.print("*\n");
        }
    }
}

die "unable to authenticate" unless $response-code eq '235';

# Send email...
...

```

# DESCRIPTION

SASL stands for Simple Authentication and Security Layer. It is really just a means of exchanging authentication strings with a service. This library implements the client-side interaction for SASL. SASL itself is complicated only in the fact that it provides a means of exchanging authentication strings, but without specifying the protocol-specific details. Therefore, to use this module for a given protocol, any encoding, error handling, or other details must be implemented by the application developer.

This API is designed to work in a very modular way. This class, `Auth::SASL`, is designed to operate as the front-end. As long as you are just making use of this module distribution to implement a SASL protocol for a client service, such as SMTP, IMAP, or LDAP, this class will provide most of what you need.

The factory objects are used to find and build mechanism objects. Mechanism objects provide handling to implement each kind of SASL authentication mechanism. The session objects provide the information about the identity that is being authenticated.

# METHODS

## method new

```
method new(Auth::SASL:U:
    Auth::SASL::Session :$session,
    Auth::SASL::Factory :$factory = Auth::SASL::Raku.new,
    --> Auth::SASL:D
)

```

Constructs an `Auth::SASL` front-end. Both arguments are optional. The `$factory` defaults to Auth::SASL::Raku, which provides a pure Raku implementation of some SASL mechanisms. Without setting `$session`, you will be required to call [.begin-session](#method begin-session) to initiate a session.

## method begin-session

```
multi method begin-session(Auth::SASL:D: Auth::SASL::Session $session)
multi method begin-session(Auth::SASL:D: :%data, :&callback)

```

Starts a new session. The session provides information about the identity being authenticated.

For simple cases, you can provide `%data` directly. These will be simple key/value pairs that provide the authentication details. The keys required will vary by the mechanisms involved.

For more complex cases you can provide a `&callback`, this will be a <Callable> routine that will be called each time a mechanism object requires a property. The callback must provide a signature compatible with:

```
sub (Str:D $property-name, Str:D :$service, Str:D :$host --> Str)

```

It should always return defined string. If it does not and the authentication method depends on that value, authentication mechansim will fail with an X::Auth::SASL::Property exception.

Finally, you can provide an object implementing Auth::SASL::Session.

## method end-session

```
method end-session(Auth::SASL:D:)

```

Clears the session. The front-end will not work until a new session is started by calling [.begin-session](#method begin-session).

## method supports-client-mechanisms

```
multi method supports-client-mechanisms(Auth::SASL:D: Str:D $mechanisms --> Bool:D)
multi method supports-client-mechanisms(Auth::SASL:D: Mixy:D $mechanisms --> Bool:D)

```

Returns a `True` value if at least one of the mechanisms listed in `$mechanisms` is supported by the current, `False` otherwise.

## method attempt-mechanisms

```
multi method attempt-mechanisms(Auth::SASL:D: Str:D $mechanisms, Str:D :$service = '', Str:D :$host = '' --> Seq:D)
multi method attempt-mechanisms(Auth::SASL:D: Mixy:D $mechanisms, Str:D :$service = '', Str:D :$host = '' --> Seq:D)

```

Once a session has been established, this method may be called to itereate over potential authentication mechanisms. The `$mechanisms` should be set to the list of mechanisms the server has reported as supporting. The factory will then use this and the list of mechanisms it supports to select the mechanisms to attempt. The <Seq> returned will allow you to iterate through 1 or more Auth::SASL::Mechanism::WorkingClient objects to use for authentication. If no compatible mechanism is found, the [X::Auth::SASL::NotFound](X::Auth::SASL#class X::Auth::SASL::NotFound) exception will be thrown.

If `$mechanisms` is passed as a string, it may either be a single mechanism name, e.g., `PLAIN`, or it it can be a space separated list of mechanism names, e.g., `PLAIN ANONYMOUS`. The factory object will determine which mechanisms are most preferable in this case.

If `$mechanisms` is passed as a <Mixy> object, such as a <Mix> or <MixHash>, the factory can use the score assigned to each key in the <Mixy> object to reorder the mechanisms and go in a different order.

The `$service` and `$host` parameters are optional and are used to allow a single session to connect to multiple services safely and even concurrently, so long as only a particular mechanism is permitted to make its attempt on a given `$service` and `$host` concurrently. The `$service` and `$host` parameters can also be used to allow a session to have multiple configurations for a given identity for different service/host combinations.


## dist_cpan-MELEZHIK-Sparky-Plugin-Notify-Email.md
# SYNOPSIS

Sparky plugin to send email notifications upon completed builds.

# INSTALL

```
$ zef install Sparky::Plugin::Notify::Email

```

# USAGE

```
$ cat sparky.yaml
# send me a notifications on failed builds
plugins:
 - Sparky::Plugin::Notify::Email:
    run_skope: fail
    parameters:
      to: melezhik@mail.me

```

# Author

Alexey Melezhik


## containers.md
Containers

A low-level explanation of Raku containers

This section explains how raw data, variables and containers relate to each other in Raku. The different types of containers used in Raku are explained and the actions applicable to them like assigning, binding and flattening. More advanced topics like self-referential data, type constraints and custom containers are discussed at the end.

For a deeper discussion of the various kinds of *ordered* containers in Raku, see the overview of [lists, sequences, and arrays](/language/list); for *unordered* containers, see [sets, bags, and mixes](/language/setbagmix).

# [What is a variable?](#Containers "go to top of document")[§](#What_is_a_variable? "direct link")

Some people like to say "everything is an object", but in fact a variable is not a user-exposed object in Raku.

When the compiler encounters a variable scope declaration like `my $x`, it registers it in some internal symbol table. This internal symbol table is used to detect undeclared variables and to tie the code generation for the variable to the correct scope.

At runtime, a variable appears as an entry in a *lexical pad*, or *lexpad* for short. This is a per-scope data structure that stores a pointer for each variable.

In the case of `my $x`, the lexpad entry for the variable `$x` is a pointer to an object of type [`Scalar`](/type/Scalar), usually just called *the container*.

# [Scalar containers](#Containers "go to top of document")[§](#Scalar_containers "direct link")

Although objects of type [`Scalar`](/type/Scalar) are everywhere in Raku, you rarely see them directly as objects, because most operations *decontainerize*, which means they act on the [`Scalar`](/type/Scalar) container's contents instead of the container itself.

In code like

```raku
my $x = 42;
say $x;
```

the assignment `$x = 42` stores a pointer to the [`Int`](/type/Int) object 42 in the scalar container to which the lexpad entry for `$x` points.

The assignment operator asks the container on the left to store the value on its right. What exactly that means is up to the container type. For [`Scalar`](/type/Scalar) it means "replace the previously stored value with the new one".

Note that subroutine signatures allow passing containers around:

```raku
sub f($a is rw) {
    $a = 23;
}
my $x = 42;
f($x);
say $x;         # OUTPUT: «23␤»
```

Inside the subroutine, the lexpad entry for `$a` points to the same container that `$x` points to outside the subroutine. Which is why assignment to `$a` also modifies the contents of `$x`.

Likewise, a routine can return a container if it is marked as `is rw`:

```raku
my $x = 23;
sub f() is rw { $x };
f() = 42;
say $x;         # OUTPUT: «42␤»
```

For explicit returns, `return-rw` instead of `return` must be used.

Returning a container is how `is rw` attribute accessors work. So

```raku
class A {
    has $.attr is rw;
}
```

is equivalent to

```raku
class A {
    has $!attr;
    method attr() is rw { $!attr }
}
```

Scalar containers are transparent to type checks and most kinds of read-only accesses. A `.VAR` makes them visible:

```raku
my $x = 42;
say $x.^name;       # OUTPUT: «Int␤»
say $x.VAR.^name;   # OUTPUT: «Scalar␤»
```

And `is rw` on a parameter requires the presence of a writable Scalar container:

```raku
sub f($x is rw) { say $x };
f 42;
CATCH { default { say .^name, ': ', .Str } };
# OUTPUT: «X::Parameter::RW: Parameter '$x' expected a writable container, but got Int value␤»
```

# [Callable containers](#Containers "go to top of document")[§](#Callable_containers "direct link")

Callable containers provide a bridge between the syntax of a [`Routine`](/type/Routine) call and the actual call of the method [CALL-ME](/type/Callable#method_CALL-ME) of the object that is stored in the container. The sigil `&` is required when declaring the container and has to be omitted when executing the [`Callable`](/type/Callable). The default type constraint is [`Callable`](/type/Callable).

```raku
my &callable = -> $ν { say "$ν is ", $ν ~~ Int ?? "whole" !! "not whole" }
callable(⅓);   # OUTPUT: «0.333333 is not whole␤»
callable(3);   # OUTPUT: «3 is whole␤»
```

The sigil has to be provided when referring to the value stored in the container. This in turn allows [`Routine`](/type/Routine)s to be used as [arguments](/language/signatures#Constraining_signatures_of_Callables) to calls.

```raku
sub f() {}
my &g = sub {}
sub caller(&c1, &c2){ c1, c2 }
caller(&f, &g);
```

# [Binding](#Containers "go to top of document")[§](#Binding "direct link")

Next to assignment, Raku also supports *binding* with the `:=` operator. When binding a value or a container to a variable, the lexpad entry of the variable is modified (and not just the container it points to). If you write

```raku
my $x := 42;
```

then the lexpad entry for `$x` directly points to the [`Int`](/type/Int) 42. Which means that you cannot assign to it anymore:

```raku
my $x := 42;
$x = 23;
CATCH { default { say .^name, ': ', .Str } };
# OUTPUT: «X::AdHoc: Cannot assign to an immutable value␤»
```

You can also bind variables to other variables:

```raku
my $a = 0;
my $b = 0;
$a := $b;
$b = 42;
say $a;         # OUTPUT: «42␤»
```

Here, after the initial binding, the lexpad entries for `$a` and `$b` both point to the same scalar container, so assigning to one variable also changes the contents of the other.

You've seen this situation before: it is exactly what happened with the signature parameter marked as `is rw`.

Sigilless variables and parameters with the trait `is raw` always bind (whether `=` or `:=` is used):

```raku
my $a = 42;
my \b = $a;
b++;
say $a;         # OUTPUT: «43␤»

sub f($c is raw) { $c++ }
f($a);
say $a;         # OUTPUT: «44␤»
```

# [Scalar containers and listy things](#Containers "go to top of document")[§](#Scalar_containers_and_listy_things "direct link")

There are a number of positional container types with slightly different semantics in Raku. The most basic one is [`List`](/type/List), which is created by the comma operator.

```raku
say (1, 2, 3).^name;    # OUTPUT: «List␤»
```

A list is immutable, which means you cannot change the number of elements in a list. But if one of the elements happens to be a scalar container, you can still assign to it:

```raku
my $x = 42;
($x, 1, 2)[0] = 23;
say $x;                 # OUTPUT: «23␤»
($x, 1, 2)[1] = 23;     # Cannot modify an immutable value
CATCH { default { say .^name, ': ', .Str } };
# OUTPUT: «X::Assignment::RO: Cannot modify an immutable Int␤»
```

So the list doesn't care about whether its elements are values or containers, they just store and retrieve whatever was given to them.

Lists can also be lazy; in that case, elements at the end are generated on demand from an iterator.

An [`Array`](/type/Array) is just like a list, except that it forces all its elements to be containers, which means that you can always assign to elements:

```raku
my @a = 1, 2, 3;
@a[0] = 42;
say @a;         # OUTPUT: «[42 2 3]␤»
```

`@a` actually stores three scalar containers. `@a[0]` returns one of them, and the assignment operator replaces the integer value stored in that container with the new one, `42`.

# [Assigning and binding to array variables](#Containers "go to top of document")[§](#Assigning_and_binding_to_array_variables "direct link")

Assignment to a scalar variable and to an array variable both do the same thing: discard the old value(s), and enter some new value(s).

Nevertheless, it's easy to observe how different they are:

```raku
my $x = 42; say $x.^name;   # OUTPUT: «Int␤»
my @a = 42; say @a.^name;   # OUTPUT: «Array␤»
```

This is because the [`Scalar`](/type/Scalar) container type hides itself well, but [`Array`](/type/Array) makes no such effort. Also assignment to an array variable is coercive, so you can assign a non-array value to an array variable.

To place a non-[`Array`](/type/Array) into an array variable, binding works:

```raku
my @a := (1, 2, 3);
say @a.^name;               # OUTPUT: «List␤»
```

# [Binding to array elements](#Containers "go to top of document")[§](#Binding_to_array_elements "direct link")

As a curious side note, Raku supports binding to array elements:

```raku
my @a = (1, 2, 3);
@a[0] := my $x;
$x = 42;
say @a;                     # OUTPUT: «[42 2 3]␤»
```

If you've read and understood the previous explanations, it is now time to wonder how this can possibly work. After all, binding to a variable requires a lexpad entry for that variable, and while there is one for an array, there aren't lexpad entries for each array element, because you cannot expand the lexpad at runtime.

The answer is that binding to array elements is recognized at the syntax level and instead of emitting code for a normal binding operation, a special method (called [`BIND-POS`](/routine/BIND-POS)) is called on the array. This method handles binding to array elements. There is also an equivalent method for binding to hash elements as well (called [`BIND-KEY`](/routine/BIND-KEY))

Note that, while supported, one should generally avoid directly binding uncontainerized things into array elements. Doing so may produce counter-intuitive results when the array is used later.

```raku
my @a = (1, 2, 3);
@a[0] := 42;         # This is not recommended, use assignment instead.
my $b := 42;
@a[1] := $b;         # Nor is this.
@a[2] = $b;          # ...but this is fine.
@a[1, 2] := 1, 2;    # runtime error: X::Bind::Slice
CATCH { default { say .^name, ': ', .Str } };
# OUTPUT: «X::Bind::Slice: Cannot bind to Array slice␤»
```

Operations that mix Lists and Arrays generally protect against such a thing happening accidentally.

# [Flattening, items and containers](#Containers "go to top of document")[§](#Flattening,_items_and_containers "direct link")

The `%` and `@` sigils in Raku generally indicate multiple values to an iteration construct, whereas the `$` sigil indicates only one value.

```raku
my @a = 1, 2, 3;
for @a { };         # 3 iterations
my $a = (1, 2, 3);
for $a { };         # 1 iteration
```

`@`-sigiled variables do not flatten in list context:

```raku
my @a = 1, 2, 3;
my @b = @a, 4, 5;
say @b.elems;               # OUTPUT: «3␤»
```

There are operations that flatten out sublists that are not inside a scalar container: slurpy parameters (`*@a`) and explicit calls to `flat`:

```raku
my @a = 1, 2, 3;
say (flat @a, 4, 5).elems;  # OUTPUT: «5␤»

sub f(*@x) { @x.elems };
say f @a, 4, 5;             # OUTPUT: «5␤»
```

You can also use `|` to create a [`Slip`](/type/Slip), introducing a list into the other.

```raku
my @l := 1, 2, (3, 4, (5, 6)), [7, 8, (9, 10)];
say (|@l, 11, 12);    # OUTPUT: «(1 2 (3 4 (5 6)) [7 8 (9 10)] 11 12)␤»
say (flat @l, 11, 12) # OUTPUT: «(1 2 3 4 5 6 7 8 (9 10) 11 12)␤»
```

In the first case, every element of `@l` is *slipped* as the corresponding elements of the resulting list. `flat`, in the other hand, *flattens* all elements including the elements of the included array, except for `(9 10)`.

As hinted above, scalar containers prevent that flattening:

```raku
sub f(*@x) { @x.elems };
my @a = 1, 2, 3;
say f $@a, 4, 5;            # OUTPUT: «3␤»
```

The `@` character can also be used as a prefix to coerce the argument to a list, thus removing a scalar container:

```raku
my $x = (1, 2, 3);
.say for @$x;               # 3 iterations
```

However, the *decont* operator `<>` is more appropriate to decontainerize items that aren't lists:

```raku
my $x = ^Inf .grep: *.is-prime;
say "$_ is prime" for @$x;  # WRONG! List keeps values, thus leaking memory
say "$_ is prime" for $x<>; # RIGHT. Simply decontainerize the Seq

my $y := ^Inf .grep: *.is-prime; # Even better; no Scalars involved at all
```

Methods generally don't care whether their invocant is in a scalar, so

```raku
my $x = (1, 2, 3);
$x.map(*.say);              # 3 iterations
```

maps over a list of three elements, not of one.

# [Self-referential data](#Containers "go to top of document")[§](#Self-referential_data "direct link")

Container types, including [`Array`](/type/Array) and [`Hash`](/type/Hash), allow you to create self-referential structures.

```raku
my @a;
@a[0] = @a;
put @a.raku;
# OUTPUT: «((my @Array_75093712) = [@Array_75093712,])␤»
```

Although Raku does not prevent you from creating and using self-referential data, by doing so you may end up in a loop trying to dump the data. As a last resort, you can use Promises to [handle](/type/Promise#method_in) timeouts.

# [Type constraints](#Containers "go to top of document")[§](#Type_constraints "direct link")

Any container can have a type constraint in the form of a [type object](/language/typesystem#Type_objects) or a [subset](/language/typesystem#subset). Both can be placed between a declarator and the variable name or after the trait [of](/type/Variable#trait_of). The constraint is a property of the variable, not the container.

```raku
subset Three-letter of Str where .chars == 3;
my Three-letter $acronym = "ÞFL";
```

In this case, the type constraint is the (compile-type defined) subset `Three-letter`.

The default type constraint of a [`Scalar`](/type/Scalar) container is [`Mu`](/type/Mu). Introspection of type constraints on containers is provided by `.VAR.of` method, which for `@` and `%` sigiled variables gives the constraint for values:

```raku
my Str $x;
say $x.VAR.of;  # OUTPUT: «(Str)␤»
my Num @a;
say @a.VAR.of;  # OUTPUT: «(Num)␤»
my Int %h;
say %h.VAR.of;  # OUTPUT: «(Int)␤»
```

## [Definedness constraints](#Containers "go to top of document")[§](#Definedness_constraints "direct link")

A container can also enforce a variable to be defined. Put a smiley in the declaration:

```raku
my Int:D $def = 3;
say $def;   # OUTPUT: «3␤»
$def = Int; # Typecheck failure
```

You'll also need to initialize the variable in the declaration, it can't be left undefined after all.

It's also possible to have this constraint enforced in all variables declared in a scope with the [default defined variables pragma](/language/variables#Default_defined_variables_pragma). People coming from other languages where variables are always defined will want to have a look.

# [Custom containers](#Containers "go to top of document")[§](#Custom_containers "direct link")

To provide custom containers Raku employs the class [`Proxy`](/type/Proxy). Its constructor takes two arguments, `FETCH` AND `STORE`, that point to methods that are called when values are fetched or stored from the container. Type checks are not done by the container itself and other restrictions like readonlyness can be broken. The returned value must therefore be of the same type as the type of the variable it is bound to. We can use [type captures](/language/signatures#Type_captures) to work with types in Raku.

```raku
sub lucky(::T $type) {
    my T $c-value; # closure variable
    return-rw Proxy.new(
        FETCH => method () { $c-value },
        STORE => method (T $new-value) {
            X::OutOfRange.new(what => 'number', got => '13', range => '-∞..12, 14..∞').throw
                if $new-value == 13;
            $c-value = $new-value;
        }
    );
}

my Int $a := lucky(Int);
say $a = 12;    # OUTPUT: «12␤»
say $a = 'FOO'; # X::TypeCheck::Binding
say $a = 13;    # X::OutOfRange
CATCH { default { say .^name, ': ', .Str } };
```


## num.md
Num

Combined from primary sources listed below.

# [In role Rational](#___top "go to top of document")[§](#(role_Rational)_method_Num "direct link")

See primary documentation
[in context](/type/Rational#method_Num)
for **method Num**.

```raku
method Num(Rational:D: --> Num:D)
```

Coerces the invocant to [`Num`](/type/Num) by dividing [numerator](/routine/numerator) by [denominator](/routine/denominator). If [denominator](/routine/denominator) is `0`, returns `Inf`, `-Inf`, or `NaN`, based on whether [numerator](/routine/numerator) is a positive number, negative number, or `0`, respectively.

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

See primary documentation
[in context](/type/Num#method_Num)
for **method Num**.

```raku
method Num()
```

Returns the invocant.

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

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

```raku
method Num(Str:D: --> Num:D)
```

Coerces the string to [`Num`](/type/Num), using the same rules as [`Str.Numeric`](/type/Str#method_Numeric) and handling negative zero, `-0e0`, and positive zero, `0e0`.

```raku
my Str $s = "-0/5";
say (.self, .^name) given $s.Numeric;  # OUTPUT: «(0 Rat)␤»
say (.self, .^name) given $s.Num;      # OUTPUT: «(-0 Num)␤»

```

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

See primary documentation
[in context](/type/NumStr#method_Num)
for **method Num**.

```raku
method Num
```

Returns the [`Num`](/type/Num) value of the `NumStr`.

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

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

```raku
multi method Num()
```

Coerces the invocant to a [`Numeric`](/type/Numeric) and calls its [`.Num`](/routine/Num) method. [Fails](/routine/fail) if the coercion to a [`Numeric`](/type/Numeric) cannot be done.

```raku
say 1+0i.Num;             # OUTPUT: «1␤»
say 2e1.Num;              # OUTPUT: «20␤»
say (16/9)².Num;          # OUTPUT: «3.1604938271604937␤»
say (-4/3).Num;           # OUTPUT: «-1.3333333333333333␤»
say "foo".Num.^name;      # OUTPUT: «Failure␤»
```

# [In role Real](#___top "go to top of document")[§](#(role_Real)_method_Num "direct link")

See primary documentation
[in context](/type/Real#method_Num)
for **method Num**.

```raku
method Num(Real:D:)
```

Calls the [`Bridge` method](/routine/Bridge) on the invocant and then the [`Num` method](/routine/Num) on its return value.


## dist_zef-andinus-antlia.md
```
           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
                                 ANTLIA
            Antlia is a text based Rock paper scissors game

                                Andinus
           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Table of Contents
─────────────────

Demo
Installation
Documentation
News

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 Website
 Source
 GitHub (mirror)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Demo
════

  This was recorded with `asciinema'.

  [https://asciinema.org/a/410736.png]

  ⁃ Antlia v0.1.0:

[https://asciinema.org/a/410736.png]

Installation
════════════

  Antlia is released to CPAN, you can get it from there or install it
  from source. In any case, `zef' is required to install the
  distribution.

  You can run Antlia without `zef'. Just run `raku -Ilib bin/antlia'
  from within the source directory.

Release
───────

  1. Run `zef install antlia'.

  Antlia should be installed, try running `antlia --version' to confirm.

From Source
───────────

  You can either download the release archive generated by cgit/GitHub
  or clone the project if you have `git' installed.

Without `git'
╌╌╌╌╌╌╌╌╌╌╌╌╌

  1. Download the release:
     •
     •
  2. Extract the file.
  3. Run `zef install .' in source directory.

With `git'
╌╌╌╌╌╌╌╌╌╌

  All commits will be signed by my [PGP Key].

  ┌────
  │ # Clone the project.
  │ git clone https://git.tilde.institute/andinus/antlia
  │ cd antlia
  │
  │ # Install octans.
  │ zef install .
  └────

[PGP Key]

Documentation
═════════════

Implementation
──────────────

  Just enter the player names & it'll print each throw along with
  scores. Press enter to play another round.

Options
───────

players
╌╌╌╌╌╌╌

  Number of players. Default is 2, should be an integer equal to or
  greater than 2.

News
════

v0.1.2 - 2021-05-25
───────────────────

  ⁃ Update dependencies in `META6.json'.

v0.1.1 - 2021-05-01
───────────────────

  ⁃ Added support for more than 2 players.
  ⁃ Prints a scorecard after the last round.

v0.1.0 - 2021-04-29
───────────────────

  Initial Implementation

```


## dist_zef-antononcube-Lingua-Stem-Russian.md
# Lingua::Stem::Russian Raku package

## Introduction

This Raku package is for stemming Russian words.
It implements the Snowball algorithm presented in
[[SNa1](http://snowball.tartarus.org/algorithms/russian/stemmer.html)].

---

## Usage examples

The `RussianStem` function is used to find stems:

```
use Lingua::Stem::Russian;
say RussianStem('всходы')

```

```
# всход

```

`RussianStem` also works with lists of words:

```
say RussianStem('Всходы урожая ожидаются с терпением, питьем и беконом.'.words)

```

```
# (Всход урож ожида с терпением, пит и беконом.)

```

The function `russian-word-stem` can be used as a synonym of `RussianStem`.

---

## Command Line Interface (CLI)

The package provides the CLI function `RussianStem`. Here is its usage message:

```
RussianStem --help

```

```
# Usage:
#   RussianStem <text> [--splitter=<Str>] [--format=<Str>] -- Finds stems of Russian words in text.
#   RussianStem [<words> ...] [--format=<Str>] -- Finds stems of Russian words.
#   RussianStem [--format=<Str>] -- Finds stems of Russian words in (pipeline) input.
#
#     <text>              Text to spilt and its words stemmed.
#     --splitter=<Str>    String to make a split regex with. [default: '\W+']
#     --format=<Str>      Output format one of 'text', 'lines', or 'raku'. [default: 'text']
#     [<words> ...]       Words to be stemmed.

```

Here are example shell commands of using the CLI function `RussianStem`:

```
RussianStem Какие

```

```
# Как

```

```
RussianStem --format=raku "Модуль Raku, предоставляющий процедуру для русского языка."

```

```
# ["Модул", "Raku", "предоставля", "процедур", "для", "русск", "язык", ""]

```

```
RussianStem Проверить корректность подбора по словарям и правилам

```

```
# Провер корректност подбор по словар и правил

```

Here is a pipeline example using the CLI function `get-tokens` of the package
["Grammar::TokenProcessing"](https://github.com/antononcube/Raku-Grammar-TokenProcessing),
[AAp1]:

```
get-tokens ./DataQueryPhrases-template | RussianStem --format=raku

# ("ассоциац", "ассоциирован", "ассоциирова", "безопасн", "восходя", "выбер", "заказа", "комбайн", "крестообразн",
#  "поверхност", "мутирова", "обзор", "обобщ", "переименова", "пол", "просмотрет", "разгруппирова", "разделител",
#  "распла", "расстав", "символ", "слит", "слиян", "сплит", "табулирова", "тольк", "убыва", "уверен", "форм",
#  "формат", "формирова", "формул", "широк")

```

**Remark:** These kind of tokens (literals) transformations are used in the packages
["DSL::Bulgarian"](https://github.com/antononcube/Raku-DSL-Bulgarian), [AAp2],
and
["DSL::Russian"](https://github.com/antononcube/Raku-DSL-Russian), [AAp3],

---

## Implementation notes

* Reprogrammed to Raku from : <https://github.com/neilb/Lingua-Stem-Ru/blob/master/lib/Lingua/Stem/Ru.pm> .

---

## TODO

* DONE Respect the word case in the returned result.

  * `RussianStem('ТАБЛА')` should return `'ТАБЛ'`.
  * (Not `'табл'` as it currently does.)
* DONE CLI that can be inserted in UNIX pipelines.
* TODO Performance statistics.
* TODO More detailed documentation.

---

## References

### Articles

[SNa1] Snowball Team,
[Russian stemming algorithm](http://snowball.tartarus.org/algorithms/russian/stemmer.html),
(2002),
[snowball.tartarus.org](http://snowball.tartarus.org).

### Packages

[AAp1] Anton Antonov,
[Grammar::TokenProcessing Raku package](https://github.com/antononcube/Raku-Grammar-TokenProcessing),
(2022),
[GitHub/antononcube](https://github.com/antononcube).

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

[AAp3] Anton Antonov,
[DSL::Russian Raku package](https://github.com/antononcube/Raku-DSL-Russian),
(2023),
[GitHub/antononcube](https://github.com/antononcube).


## dist_zef-jonathanstowe-WebService-Soundcloud.md
# WebService::Soundcloud

Provide a Raku interface to the Soundcloud REST API.

![Build Status](https://github.com/jonathanstowe/WebService-Soundcloud/workflows/CI/badge.svg)

## Synopsis

You can use the Full OAuth flow:

```

    use WebService::Soundcloud;

    my $scloud = WebService::Soundcloud.new(:$client-id, :$client-secret, redirect-uri => 'http://mydomain.com/callback' );

    # Now get authorization url
    my $authorization_url = $scloud.get-authorization-url();

    # Now your appplication should redirect the user to the authorization uri
    # When the User has authenticated and approved the connection they will
    # in turn be redirected back to your redirect URI with either the grant code
    # (as code) or an error (as error) as query parameters

    # Get Access Token with the code provided as query parameter to the redirect
    my $access_token = $scloud.get-access-token($code);

    # Save access_token and refresh_token, expires_in, scope for future use
    my $oauth_token = $access_token<access_token>;

    # a GET request '/me' - gets users details
    my $user = $scloud->get('/me');

    # a PUT request '/me' - updated users details
    my $user = $scloud->put('/me', to-json( { user => { description => 'Have fun with the Raku wrapper to Soundcloud API' } } ) );

    # Comment on a Track PoSt request usage
    my $comment = $scloud->post('/tracks/<track_id>/comments',
                            { body => 'I love this hip-hop track' } );

    # Delete a track
    my $track = $scloud->delete('/tracks/{id}');

```

or you can use direct credential based authorisation that can skip the redirections:

```

    use WebService::Soundcloud;

    my $sc = WebService::Soundcloud.new(:$client-id,:$client-secret,:$username,:$password);

    # Because the credentials were provided  the access-token can be requested directly
    # without the need for a grant code
    my $token = $sc.get-access-token();
    my $me = $sc.get-object('/me');
    my $tracks = $sc.get-list('/me/tracks');

```

## Description

This provides an interface to the [Soundcloud
API](https://developers.soundcloud.com/docs/api/reference), managing
the authorisation, connection and marshalling of the data.

You can build client side applications that authenticate with user
credentials or server applications that use the full OAuth authorization.

In order to use this module you will need to register your application
with Soundcloud at <http://soundcloud.com/you/apps> : your application will
be given a client ID and a client secret which you will need to use to
connect. The client ID used in the tests will not work correctly for your
own application as the callback URI is set to 'localhost'.

## Installation

If you have a working Rakudo installation can install directly with "zef":

```
# From the source directory

zef install .

# Remote installation

zef install WebService::Soundcloud

```

## Support

Suggestions/patches are welcomed via github at:

<https://github.com/jonathanstowe/WebService-Soundcloud/issues>

## Licence

This is free software.

Please see the <LICENCE> file in the distribution

© Jonathan Stowe 2015 - 2021


## dist_cpan-ANTONOV-Data-Generators.md
# Raku Data::Generators

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

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

### Motivation

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

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

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

```

---

## Random strings

The function `random-string` generates random strings.

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

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

```

```
# ("115y", "y9Yn", "n7N9", "16YN", "1083", "58Y0")

```

---

## Random words

The function `random-word` generates random words.

Here we generate a list with 12 random words:

```
random-word(12)

```

```
# (service smooth-bodied Oniscidae scurf corkage commensally Lozal witchery convection chickweed hueless anthropometrical)

```

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

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

```

```
# +--------+------------+--------------+-----------+---------------+------------+---------------+
# |        |     2      |      3       |     0     |       5       |     4      |       1       |
# +--------+------------+--------------+-----------+---------------+------------+---------------+
# | Any    | Wykehamist |  euthanasia  |  Estronol | supplementary |    a.m.    |     tacit     |
# | Common |  stutter   | studiousness |   loggia  |    rhinitis   | roundabout | circumstances |
# | Known  |  Goldwyn   |  commotion   | Tocharian |     stolid    | doctorfish |     fulfil    |
# | Stop   |   how's    |   between    |     i     |     he'll     |   whole    |     hasn't    |
# +--------+------------+--------------+-----------+---------------+------------+---------------+

```

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

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

---

## Random pet names

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

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

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

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

```

```
# ("Margot", "Millie", "Roberta", "Tati", "Chewie", "Tati")

```

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

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

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

```

```
# +------+----------+------------------+-----------------------+----------+-----------+-----------+
# |      |    4     |        5         |           2           |    0     |     3     |     1     |
# +------+----------+------------------+-----------------------+----------+-----------+-----------+
# | Any  | Guinness | Sister Bertrille |        Roswell        |  Tanner  |  Guinness |  Atticus  |
# | Cat  | Nibbles  |       male       | The Little Muffin Man |   Ink    | Schmeeber | Safi-Sana |
# | Dog  |  Yummy   |      Abita       |         Sonoma        |  Peeve   |    Hook   |   Merfy   |
# | Goat |  Frosty  |       Arya       |         Pepina        |  Tacoma  |   Darcy   |   Piper   |
# | Pig  | Guinness |     Atticus      |        Guinness       | Guinness |  Atticus  |   Millie  |
# +------+----------+------------------+-----------------------+----------+-----------+-----------+

```

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

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

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

```

```
# ("Tati", "Miss Scarlett", "Millie", "Professor Nibblesworth", "Atticus", "Atticus")

```

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

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

---

## Random pretentious job titles

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

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

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

```

```
# ("International Paradigm Manager", "National Security Planner", "Forward Response Associate", "Global Marketing Executive", "Interactive Tactics Strategist", "Dynamic Marketing Representative")

```

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

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

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

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

```

```
# +-------------------------------+-----------------------------------+---------------------------+
# |               0               |                 1                 |             2             |
# +-------------------------------+-----------------------------------+---------------------------+
# | Областен Асистент на Интранет | Вътрешен Консултант на Показатели |    Lead Group Designer    |
# |        Data Coordinator       |               Техник              | Старши Проектант по Екипи |
# |   Lead Security Coordinator   |             Synergist             |   Стратег по Комуникации  |
# |           Проектант           |   Национален Инженер по Фактори   |          Дизайнер         |
# +-------------------------------+-----------------------------------+---------------------------+

```

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

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

---

## Random reals

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

Here are examples:

```
say random-variate(NormalDistribution.new(:mean(10), :sd(20)), 5);

```

```
# (-18.615180334983382 -14.777307898313193 11.744540271606233 32.83415351542184 23.05439201645865)

```

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

```

```
# (35.82804554696579 -12.643547444336193 16.320377789979375 27.16893715675326 14.117125819449708)

```

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

```

```
# (27.66534628863628 15.022852723841478 41.15611113824118 54.085283581723125 57.46240753137406)

```

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

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

Here is an example of 2D array generation:

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

```

```
# [[-0.4479067963939533 0.28167926816285005 -1.075347558796815 1.3360794891272738]
#  [1.4424534618996863 -1.0817181852485276 1.1124463316112607 0.8958722847013001]
#  [0.9971898647548 0.5300761587505801 -0.19123738083454592 -0.04397620670389424]]

```

---

## Random tabular datasets

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

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

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

Here are basic calls:

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

```

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

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

```

```
# +----------+--------------------+----------------+
# |  Winton  |      Liliquoi      |    Cheddar     |
# +----------+--------------------+----------------+
# |  Praia   | 19.859813619203255 |    musingly    |
# | schlock  | 21.238698325857193 |    prudery     |
# |  Dacca   | 21.52325074237404  | oleaginousness |
# |  drably  | 22.069553581961273 |   underside    |
# | complain | 12.188987647044241 |  latticework   |
# +----------+--------------------+----------------+

```

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

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

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

---

## TODO

1. Random tabular datasets generation

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

   * Uniform distribution
   * Normal distribution
   * Poisson distribution
   * Skew-normal distribution
   * Triangular distribution
5. Selection between `roll` and `pick` for:

   * `RandomWord`
   * `RandomPetName`

---

## References

### Articles

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

### Functions, packages

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

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

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

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

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

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

### Data repositories

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


## dist_github-ramiroencinas-System-Stats-DISKUsage.md
# System::Stats::DISKUsage

[![Build Status](https://travis-ci.com/ramiroencinas/System-Stats-DISKUsage.svg?branch=master)](https://travis-ci.com/github/ramiroencinas/System-Stats-DISKUsage)

Raku module - Provides Disk Usage Stats.

## OS Supported:

* GNU/Linux (Kernel 2.6+) by /proc/diskstats

## Installing the module

```
zef update
zef install System::Stats::DISKUsage

```

## Example Usage:

```
use v6;
use System::Stats::DISKUsage;

my %diskUsage = DISK_Usage();

say "\nDisk Usage per second:\n";
say "Drive BytesRead BytesWritten\n";

for %diskUsage.sort(*.key)>>.kv -> ($drive, $usage) {

	printf "%-5s %-9d %-d\n", $drive, $usage<bytesreadpersec>, $usage<byteswrittenpersec>;

}

```

## TODO:

* Win32 version.


## dist_cpan-SAMGWISE-Structable.md
[![Build Status](https://travis-ci.org/samgwise/p6-structable.svg?branch=master)](https://travis-ci.org/samgwise/p6-structable)

# NAME

Structable - Runtime validation of associative datastructures

# SYNOPSIS

```
use Structable;

# Define the structure of a record
my $struct = struct-def
    (struct-int    'id_weight'),
    (struct-str    'name_subject'),
    (struct-rat    'weight_subject'),
    (struct-date   'date_measure');

# Conform an acceptable Map to the given structure
say conform($struct,
    { id_weight         => 1
    , name_subject      => 'Foo'
    , weight_subject    => 3.21
    , date_measure      => '2019-01-25'
    }
).ok("Err conforming to struct.").perl;
# output ${:date_measure(Date.new(2019,1,25)), :id_weight(1), :name_subject("Foo"), :weight_subject(3.21)}

# A bad Map of values, something is missing...
{
    my $result = conform($struct,
        { not_the_id        => 2
        , name_subject      => 'Bar'
        , weight_subject    => 1.23
        , date_measure      => '2019-01-25'
        }
    );

    given $result {
        when .is-err {
            .error.say
        }
    }
}
# output: Unable to find value for 'id_weight', keys provided were: 'not_the_id', 'date_measure', 'name_subject', 'weight_subject'

# A good map after some coercion
say conform($struct,
    { id_weight         => "3" #Now it's an Str, just like you commonly find being returned from a parsed JSON document
    , name_subject      => 'Baz'
    , weight_subject    => "7.65"
    , date_measure      => '2019-01-25'
    , Something_extra   => False
    }
).ok("Err conforming to struct").perl;
# output: ${:date_measure(Date.new(2019,1,25)), :id_weight(3), :name_subject("Baz"), :weight_subject(7.65)}
# The conformed values have been coerced into their specified types

# Converting complex types back to a simple structure
say simplify($struct,
    { id_weight         => 3
    , name_subject      => 'Baz'
    , weight_subject    => 7.65
    , date_measure      => Date.new('2019-01-25')
    }
).ok("Err performing simplification with struct").perl;
# output: ${:date_measure("2019-01-25"), :id_weight(3), :name_subject("Baz"), :weight_subject(7.65)}
# The conformed values have been coerced into their specified types

```

# DESCRIPTION

The Structable module provides a mechanism for defining an ordered and typed data definition.

Validating input like JSON is often a tedious task, however with Structable you can create concise definitions which you can apply at runtime. If the input is valid (perhaps with a bit of coercion) then the conformed data will be returned in a Result::Ok object and if there was something wrong, a Result::Err will be returned with a helpful error message. This means that you can use conform operations in a stream of values instead of resorting to try/catch constructs to handle your validation errors.

The struct definition also defines an order, so by grabbing a list of keys you can easily iterate over values in a conformed Map in a uniformly specified order.

## Custom types

If you need more types than those bundled in this module you can add your own! All members of a Strucatable::Struct are Structable::Type[T], a parametric role. Simply pass your type as the role's type parameter and away you go.

## Caveats

Although this module helps provide assurances about the data you are injesting it has not yet been audited and tested to provide any assurances regarding security. Data from an unstrusted source may still be untrustworthy after passing through a conform step provided by this module. Particular caution should be given to the size of payload you are conforming, there are no inbuilt mechanisims to prevent this style of abuse in this module.

# AUTHOR

Sam Gillespie [samgwise@gmail.com](mailto:samgwise@gmail.com)

# COPYRIGHT AND LICENCE

Copyright 2018 Sam Gillespie

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

## class Mu $

Generic role defining the Structable::Type interface. This role is punnable for scalar container types and specilisable for collection types.

### sub struct-def

```
sub struct-def(
    +@members
) returns Structable::Struct

```

A factory for defining a new C defenition. Each argument must be a CStructable::Type and is checked on execution of this function.

### sub conform

```
sub conform(
    Structable::Struct:D $s,
    Map:D $m
) returns Result::Any

```

This subroutine attempts to conform a Map (such as a Hash) to a given struct. The outcome is returned as a C object. A CResult::Ok holds a filtered version of a hash which adhears to the given struct. A CResult::Err represents an error and holds an error message describing why the given Map is not conformant to the given Struct.

### sub str-to-int

```
sub str-to-int(
    $val
) returns Result::Any

```

A simple coercer for mapping a Str of Int to Int If you can call Int on it, it'll be acceptable as an Int. This routine is package scoped and not exported when used.

### sub str-to-rat

```
sub str-to-rat(
    $val
) returns Result::Any

```

A simple coercer for mapping a Str of Rat to Rat If you can call Int on it, it'll be acceptable as an Int. This routine is package scoped and not exported when used.

### sub struct-int

```
sub struct-int(
    Str:D $name,
    Bool :$optional,
    Bool :$maybe,
    :$default
) returns Structable::Type

```

A factory for creating a struct element of type Int. By default this Type element will try and coerce Str values to Int.

### sub buf-to-str

```
sub buf-to-str(
    $val
) returns Result::Any

```

A simple coercer for mapping a Buf of Str to Str If you can call decode on it, it'll be acceptable as an Str. This routine is package scoped and not exported when used.

### sub struct-str

```
sub struct-str(
    Str:D $name,
    Bool :$optional,
    Bool :$maybe,
    :$default
) returns Structable::Type

```

A factory for creating a struct element of type Str No coercion behaviours are defined for this Type

### sub struct-rat

```
sub struct-rat(
    Str:D $name,
    Bool :$optional,
    Bool :$maybe,
    :$default
) returns Structable::Type

```

A factory for creating a struct element of type Rat. By default this Type element will try and coerce Str values to Rat.

### sub str-to-date

```
sub str-to-date(
    $val
) returns Result::Any

```

A simple coercer for mapping a Str containing a date string to a Date object This routine is package scoped and not exported when used.

### sub struct-date

```
sub struct-date(
    Str:D $name,
    Bool :$optional,
    Bool :$maybe,
    :$default
) returns Structable::Type

```

A factory for creating a struct element of type Date. Coerces date strings to Dat objects according to inbuild Date object behaviour.

### sub str-to-datetime

```
sub str-to-datetime(
    $val
) returns Result::Any

```

A simple coercer for mapping a Str containing an ISO time stamp string to a DateTime object This routine is package scoped and not exported when used.

### sub struct-datetime

```
sub struct-datetime(
    Str:D $name,
    Bool :$optional,
    Bool :$maybe,
    :$default
) returns Structable::Type

```

A factory for creating a struct element of type DateTime. Coerces date strings to Dat objects according to inbuild Date object behaviour.

### sub any-to-bool

```
sub any-to-bool(
    $val
) returns Result::Any

```

A Bool coercer, searching for truethy values. Since a simple coercer could just return a .so result, this function is a little more aggressive. .so logic is applied but strings are also checked for empty string and the string '0'.

### sub struct-bool

```
sub struct-bool(
    Str:D $name,
    Bool :$optional,
    Bool :$maybe,
    Bool :$default
) returns Structable::Type

```

A factory for creating a struct element of type Bool. A struct def for Bool types, this is built with the any-to-bool coercion function.

### sub struct-nested

```
sub struct-nested(
    Str:D $name,
    Structable::Struct $struct,
    :$optional = Bool::False,
    :$default,
    :&coercion,
    :&to-simple
) returns Mu

```

A factory for creating a struct element of another Structable::Struct. The provided struct will be used for simplifying and conforming the nested values. Conform and simplify actions cascade into the defenition.

### sub struct-list

```
sub struct-list(
    Str:D $name,
    Structable::Type $list-type,
    :$optional = Bool::False,
    :$default,
    :&coercion,
    :&to-simple
) returns Mu

```

A factory for creating a struct element list defenition. The List must be of a uniform type as specified by the Structable type provided. Conform and simplify actions cascade into the defenition.

### sub any-to-str

```
sub any-to-str(
    $val
) returns Result::Any

```

A basic simplifier which calls the .Str method to perform simplification This routine is package scoped and not exported when the module is used.

### sub simplify

```
sub simplify(
    Structable::Struct:D $s,
    Map:D $m
) returns Result::Any

```

Pack a given map according to a given struct. This function is the complement of conform and facilitates packing a map down to a simple map, ready for serialisation to a format such as JSON.


## race.md
race

Combined from primary sources listed below.

# [In role Iterable](#___top "go to top of document")[§](#(role_Iterable)_method_race "direct link")

See primary documentation
[in context](/type/Iterable#method_race)
for **method race**.

```raku
method race(Int(Cool) :$batch = 64, Int(Cool) :$degree = 4 --> Iterable)
```

Returns another Iterable that is potentially iterated in parallel, with a given batch size and degree of parallelism (number of parallel workers).

Unlike [`hyper`](/routine/hyper), `race` does not preserve the order of elements (mnemonic: in a race, you never know who will arrive first).

```raku
say ([1..100].race.map({ $_ +1 }).list);
```

Use race in situations where it is OK to do the processing of items in parallel, and the output order does not matter. See [`hyper`](/routine/hyper) for situations where you want items processed in parallel and the output order should be kept relative to the input order.

**[Blog post on the semantics of hyper and race](https://6guts.wordpress.com/2017/03/16/considering-hyperrace-semantics/)**

See [`hyper`](/routine/hyper) for an explanation of `:$batch` and `:$degree`.

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

See primary documentation
[in context](/type/HyperSeq#method_race)
for **method race**.

```raku
method race(HyperSeq:D:)
```

Creates a [`RaceSeq`](/type/RaceSeq) object out of the current one.

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

See primary documentation
[in context](/type/RaceSeq#method_race)
for **method race**.

```raku
method race(RaceSeq:D:)
```

Returns the object.


## dist_github-avuserow-Binary-Structured.md
# NAME

Binary::Structured - read and write binary formats defined by classes

# SYNOPSIS

```
use Binary::Structured;

# Binary format definition
class PascalString is Binary::Structured {
    has uint8 $!length is written(method {$!string.bytes});
    has Buf $.string is read(method {self.pull($!length)}) is rw;
}

# Reading
my $parser = PascalString.new;
$parser.parse(Buf.new("\x05hello world".ords));
say $parser.string.decode("ascii"); # "hello"

# Writing
$parser.string = Buf.new("some new data".ords);
say $parser.build; # Buf:0x<0d 73 6f 6d 65 20 6e 65 77 20 64 61 74 61>

```

# DESCRIPTION

Binary::Structured provides a way to define classes which know how to parse and emit binary data based on the class attributes. The goal of this module is to provide building blocks to describe an entire file (or well-defined section of a file), which can easily be parsed, edited, and rebuilt.

This module was inspired by the Python library `construct`, with the class-based representation inspired by Perl 6's `NativeCall`.

Types of the attributes are used whenever possible to drive behavior, with custom traits provided to add more smarts when needed to parse more formats.

These attributes are parsed in order of declaration, regardless of if they are public or private, but only attributes declared in that class directly. The readonly or rw traits are ignored for attributes. Methods are also ignored.

WARNING: As this is a pre-1.0 module, the API is subject to change between versions without deprecation.

# TYPES

Perl 6 provides a wealth of native sized types. The following native types may be used on attributes for parsing and building without the help of any traits:

* int8
* int16
* int32
* uint8
* uint16
* uint32

These types consume 1, 2, or 4 bytes as appropriate for the type. These values are interpreted as little endian by default. Big endian representations may be indicated by using the `is big-endian` trait, see the traits section below.

* Buf

Buf is another type that lends itself to representing this data. It has no obvious length and requires the `read` trait to consume it (see the traits section below).

Note that you can provide both `is read` and `is written` to compute the value when parsing and building, allowing you to put in arbitrary bytes at this position. See `StreamPosition` below if you just want to keep track of the current position.

* StaticData

A variant of Buf, `StaticData`, is provided to represent bytes that are known in advance. It requires a default value of a Buf, which is used to determine the number of bytes to consume, and these bytes are checked with the default value. An exception is raised if these bytes do not match. An appropriate use of this would be the magic bytes at the beginning of many file formats, or the null terminator at the end of a CString, for example:

```
# Magic for PNG files
class PNGFile is Binary::Structured {
    has StaticData $.magic = Buf.new(0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a);
}

```

* StreamPosition

This exported class consumes no bytes, and writes no bytes. It just records the current stream position into this attribute when reading or writing so other variables can reference it later. Reader and writer traits are ignored on this attribute.

* StreamEvent

This exported class consumes no bytes, and writes no bytes. It executes the `is read` and `is written` attributes, allowing you to put arbitrary code in the parse or build process at this point. This is a good place to put a call to `rewrite-attribute`, allowing you to update a previous value once you know what it should be.

* Binary::Structured subclass

These structures may be nested. Provide an attribute that subclasses `Binary::Structured` to include another structure at this position. This inner structure takes over control until it is done parsing or building, and then the outer structure resumes parsing or building.

```
class Inner is Binary::Structured {
    has int8 $.value;
}
class Outer is Binary::Structured {
    has int8 $.before;
    has Inner $.inner;
    has int8 $.after;
}
# This would be able to parse Buf.new(1, 2, 3)
# $outer.before would be 1, $outer.inner.value would be 2,
# and $outer.after would be 3.

```

* Array[Binary::Structured]

Multiple structures can be handled by using an `Array` of subclasses. Use the `read` trait to control when it stops trying to adding values into the array. See the traits section below for examples on controlling iteration.

# METHODS

## class X::Binary::Structured::StaticMismatch

Exception raised when data in a C does not match the bytes consumed.

## class Binary::Structured

Superclass of formats. Some methods are meant for implementing various trait helpers (see below).

### has Int $.pos

Current position of parsing of the Buf.

### has Blob $.data

Data being parsed.

### method peek

```
method peek(
    Int $count
) returns Mu

```

Returns a Buf of the next C<$count> bytes but without advancing the position, used for lookahead in the C trait.

### method peek-one

```
method peek-one() returns Mu

```

Returns the next byte as an Int without advancing the position. More efficient than regular C, used for lookahead in the C trait.

### method pull

```
method pull(
    Int $count
) returns Mu

```

Method used to consume C<$count> bytes from the data, returning it as a Buf. Advances the position by the specified count.

### method pull-elements

```
method pull-elements(
    Int $count
) returns ElementCount

```

Helper method for reader methods to indicate a certain number of elements/iterations rather than a certain number of bytes.

### method rewrite-attribute

```
method rewrite-attribute(
    Str $attribute
) returns Mu

```

Helper method to rewrite a previous attribute that is marked C. Only works on seekable buffers and may not change the length of the buffer. Specify the attribute via string using the C<$!foo> syntax (regardless of if it is public or private).

### method parse

```
method parse(
    Blob $data,
    Int :$pos = 0
) returns Mu

```

Takes a Buf of data to parse, with an optional position to start parsing at.

### method build

```
method build() returns Blob

```

Construct a C from the current state of this object.

# TRAITS

Traits are provided to add additional parsing control. Most of them take methods as arguments, which operate in the context of the parsed (or partially parsed) object, so you can refer to previous attributes.

## `is read`

The `is read` trait controls reading of `Buf`s and `Array`s. For `Buf`, return a `Buf` built using `self.pull($count)` (to ensure the position is advanced properly). `$count` here could be a reference to a previously parsed value, could be a constant value, or you can use a loop along with `peek-one`/`peek` to concatenate to a Buf.

For `Array`, return a count of bytes as an `Int`, or return a number of elements to read using `self.pull-elements($count)`. Note that `pull-elements` does not advance the position immediately so `peek` is less useful here.

## `is written`

The `is written` trait controls how a given attribute is constructed when `build` is called. It provides a way to update values based on other attributes. It's best used on things that would be private attributes, like lengths and some checksums. Since `build` is only called when all attributes are filled, you can refer to attributes that have not been written (unlike `is read`).

## `is big-endian`

Applies to native integers (int16, int32, uint16, uint32), and indicates that this value should be read and written as a big endian value (with the most significant byte first) rather than the default of little endian.

## `is little-endian`

Little endian is the default for numeric values, but the trait is provided for completeness.

# REQUIREMENTS

* Rakudo Perl v6.c or above (tested on 2016.08.1)

# TODO

See <TODO>.


## notification.md
class IO::Notification

Asynchronous notification for file and directory changes

```raku
enum FileChangeEvent (:FileChanged(1), :FileRenamed(2));

```

```raku
class IO::Notification {}

```

Essentially, this class exists as a placeholder for the `IO::Notification.watch-path($path)` method, that produces a [`Supply`](/type/Supply) of [`IO::Notification::Change`](/type/IO/Notification/Change) events for a file or directory.

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

## [method watch-path](#class_IO::Notification "go to top of document")[§](#method_watch-path "direct link")

```raku
method watch-path(IO::Notification: Str() $path, :$scheduler = $*SCHEDULER)

```

Returns a [`Supply`](/type/Supply) that emits [`IO::Notification::Change`](/type/IO/Notification/Change) objects.

If `$path` is a file, only modifications of that file are reported. If `$path` is a directory, both modifications to the directory itself (for example permission changes) and to files in the directory (including new files in the directory) are reported.

The `:$scheduler` named argument allows you to specify which thread scheduler is going to be responsible for the notification stream; it can be omitted if the default scheduler is used.

```raku
my $supply = IO::Notification.watch-path( "/var/log/syslog" );

$supply.tap( -> $v { say "Got ", $v });

sleep 60;

```

This snippet of code sets a watch on the system log file, emitting the kind of event that has occurred or capturing an error otherwise; the created [`Supply`](/type/Supply) is tapped, and the event printed. It does so for 60 minutes, emitting something like this:

｢text｣ without highlighting

```

```

Got /var/log/syslog: FileChanged
Got /var/log/syslog: FileChanged
Got /var/log/syslog: FileChanged
Got /var/log/syslog: FileChanged
Got /var/log/syslog: FileChanged
Got /var/log/syslog: FileChanged
Got /var/log/syslog: FileChanged
Got /var/log/syslog: FileChanged

```

```

The only kind of information this method provides is the bare fact that something has change or been renamed. You will need to actually open and read the file or directory to check the actual changes.


## numerator.md
numerator

Combined from primary sources listed below.

# [In X::Numeric::DivideByZero](#___top "go to top of document")[§](#(X::Numeric::DivideByZero)_method_numerator "direct link")

See primary documentation
[in context](/type/X/Numeric/DivideByZero#method_numerator)
for **method numerator**.

```raku
method numerator()
```

If present, returns the numerator of the operation.

# [In role Rational](#___top "go to top of document")[§](#(role_Rational)_method_numerator "direct link")

See primary documentation
[in context](/type/Rational#method_numerator)
for **method numerator**.

```raku
method numerator(Rational:D: --> NuT:D)

```

Returns the numerator.


## chr.md
chr

Combined from primary sources listed below.

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

See primary documentation
[in context](/type/Int#routine_chr)
for **routine chr**.

```raku
multi        chr(Int:D  --> Str:D)
multi method chr(Int:D: --> Str:D)
```

Returns a one-character string, by interpreting the integer as a Unicode codepoint number and converting it to the corresponding character.

Example:

```raku
65.chr;  # returns "A"
196.chr; # returns "Ä"
```

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

See primary documentation
[in context](/type/Cool#routine_chr)
for **routine chr**.

```raku
sub chr(Int(Cool))
method chr()
```

Coerces the invocant (or in sub form, its argument) to [`Int`](/type/Int), interprets it as a [Unicode code points](https://en.wikipedia.org/wiki/Code_point), and returns a [`Str`](/type/Str) made of that code point.

```raku
say '65'.chr;       # OUTPUT: «A␤»
```

The inverse operation is [ord](/routine/ord).

Mnemonic: turns an integer into a *char*acter.


## unlesselse.md
class X::Syntax::UnlessElse

Compilation error due to an `unless` clause followed by `else`

```raku
class X::Syntax::UnlessElse does X::Syntax { }
```

Syntax error thrown when an `unless` clause is followed by an `else` clause.

For example

```raku
unless 1 { } else { };

```

dies with

｢text｣ without highlighting

```

```

===SORRY!===
"unless" does not take "else", please rewrite using "if"

```

```


## classify.md
classify

Combined from primary sources listed below.

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

See primary documentation
[in context](/type/Any#routine_classify)
for **routine classify**.

```raku
multi method classify()
multi method classify(Whatever)
multi method classify($test, :$into!, :&as)
multi method classify($test, :&as)
multi        classify($test, +items, :$into!, *%named )
multi        classify($test, +items, *%named )
```

The first form will always fail. The second form classifies on the identity of the given object, which usually only makes sense in combination with the `:&as` argument.

The rest include a `$test` argument, which is a function that will return a scalar for every input; these will be used as keys of a hash whose values will be arrays with the elements that output that key for the test function.

```raku
my @years = (2003..2008).map( { Date.new( $_~"-01-01" ) } );
@years.classify( *.is-leap-year , into => my %leap-years );
say %leap-years;
# OUTPUT: «{False => [2003-01-01 2005-01-01 2006-01-01 2007-01-01],
#           True => [2004-01-01 2008-01-01]}␤»

```

Similarly to [`.categorize`](/type/Any#routine_categorize), elements can be normalized by the [`Callable`](/type/Callable) passed with the `:as` argument, and it can use the `:into` named argument to pass a [`Hash`](/type/Hash) the results will be classified into; in the example above, it's defined on the fly.

From version 6.d, `.classify` will also work with [`Junction`](/type/Junction)s.

Support for using [`Whatever`](/type/Whatever) as the test was added in Rakudo compiler version 2023.02.

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

See primary documentation
[in context](/type/List#routine_classify)
for **routine classify**.

```raku
multi method classify($test, :$into!, :&as)
multi method classify($test, :&as)
multi        classify($test, +items, :$into!, *%named )
multi        classify($test, +items, *%named )
```

Transforms a list of values into a hash representing the classification of those values; each hash key represents the classification for one or more of the incoming list values, and the corresponding hash value contains an array of those list values classified into the category of the associated key. `$test` will be an expression that will produce the hash keys according to which the elements are going to be classified.

Example:

```raku
say classify { $_ %% 2 ?? 'even' !! 'odd' }, (1, 7, 6, 3, 2);
# OUTPUT: «{even => [6 2], odd => [1 7 3]}␤»
say ('hello', 1, 22/7, 42, 'world').classify: { .Str.chars };
# OUTPUT: «{1 => [1], 2 => [42], 5 => [hello world], 8 => [3.142857]}␤»
```

It can also take `:as` as a named parameter, transforming the value before classifying it:

```raku
say <Innie Minnie Moe>.classify( { $_.chars }, :as{ lc $_ });
# OUTPUT: «{3 => [moe], 5 => [innie], 6 => [minnie]}␤»
```

This code is classifying by number of characters, which is the expression that has been passed as `$test` parameter, but the `:as` block lowercases it before doing the transformation. The named parameter `:into` can also be used to classify *into* a newly defined variable:

```raku
<Innie Minnie Moe>.classify( { $_.chars }, :as{ lc $_ }, :into( my %words{Int} ) );
say %words; # OUTPUT: «{3 => [moe], 5 => [innie], 6 => [minnie]}␤»
```

We are declaring the scope of `%words{Int}` on the fly, with keys that are actually integers; it gets created with the result of the classification.


## dist_github-retupmoca-Compress-Zlib-Raw.md
# Compress::Zlib::Raw

[![Build Status](https://travis-ci.org/retupmoca/P6-Compress-Zlib-Raw.svg?branch=master)](https://travis-ci.org/retupmoca/P6-Compress-Zlib-Raw) [![Build status](https://ci.appveyor.com/api/projects/status/github/retupmoca/P6-Compress-Zlib-Raw?svg=true)](https://ci.appveyor.com/project/retupmoca/P6-Compress-Zlib-Raw/branch/master)

Low-level interface to zlib.

Note: This will probably only work on 64bit \*nix, due to hardcoded library name
and `sizeof` numbers.

##Example

```
use v6;

use Compress::Zlib::Raw;
use NativeCall;

my $to-compress = "test".encode;

my $return-buf-len = CArray[long].new;
$return-buf-len[0] = 128;

my $return-buf = buf8.new;
$return-buf[127] = 0;

my $result = compress($return-buf, $return-buf-len, $to-compress, 4);
die if $result != Compress::Zlib::Raw::Z_OK;

my $orig-buf = buf8.new;
$orig-buf[127] = 1;

my $orig-size = CArray[long].new;
$orig-size[0] = 128;

$result = uncompress($orig-buf, $orig-size, $return-buf, $return-buf-len[0]);
die if  $result != Compress::Zlib::Raw::Z_OK;

```

## Author

Andrew Egeler, retupmoca on #perl6, <https://github.com/retupmoca/>

## License

MIT License


## dist_cpan-PMQS-Raku-GitHub-Workflows.md
# Raku GitHub Workflows

![Raku Caching Test](https://github.com/pmqs/Raku-GitHub-Workflows/workflows/Raku%20Caching%20Test/badge.svg)
![Linux Docker Test](https://github.com/pmqs/Raku-GitHub-Workflows/workflows/Linux%20Docker%20Test/badge.svg)
![Linux Star Docker Test](https://github.com/pmqs/Raku-GitHub-Workflows/workflows/Linux%20Star%20Docker%20Test/badge.svg)
![MacOS Star Test](https://github.com/pmqs/Raku-GitHub-Workflows/workflows/MacOS%20Star%20Test/badge.svg)
![Windows Star Test](https://github.com/pmqs/Raku-GitHub-Workflows/workflows/Windows%20Star%20Test/badge.svg)

This distribution contains a number of GitHub workflows that can be used for testing [Raku](https://www.raku.org/) (Perl6) modules. The Raku code under `lib` and `t` is just dummy code that acts as a test harness for the workflows. Look in `.github/workflows` for the real deliverables from this dstribution.

## Summary of Workflows Available

The workflows vary in the amount of control they have over the version of Raku used and the OS they run on. The table below summarised the feature set available in each.

| Workflow File | OS Supported | Raku Origin | Uses [Rakudo Star](https://rakudo.org/star) | Control Raku Version Used | Option To Run Latest Raku | GitHub Cache Support |
| --- | --- | --- | --- | --- | --- | --- |
| wf-caching.yml | Linux, MacOS & Windows | [Rakudo Downloads](https://rakudo.org/downloads/rakudo) | No | Yes | Yes | Yes |
| wf-linux-docker.yml | Linux | [Docker](https://hub.docker.com/r/jjmerelo/alpine-raku) | No | Yes | Yes | No |
| wf-linux-star-docker.yml | Linux | [Rakudo Star Official Docker](https://hub.docker.com/_/rakudo-star/) | Yes | Yes | Yes | No |
| wf-macos-star.yml | MacOS | [Homebrew](https://github.com/Homebrew/homebrew-core/blob/master/Formula/rakudo-star.rb) | Yes | No | No | No |
| wf-windows-star.yml | Windows | [Chocolatey](https://chocolatey.org/packages/rakudostar) | Yes | No | No | No |

## Which one should you use?

For casual testing, one of the workflows that use [Rakudo Star](https://rakudo.org/star) is a good starting point. They usually have a relatively recent build of Raku, plus they come with a set of commonly used modules. Less chance of needing any prerequisite modules to be installed.

## Why you may need a Caching Workflow

All the workflows use the [zef](https://github.com/ugexe/zef) Module Manager to automatically install Raku depencencies. If you are using a workflow that uses [Rakudo Star](https://rakudo.org/star) there may be no need to install any. [Rakudo Star](https://rakudo.org/star) may already include them.

If you have a use-case where your module dependencies are not present in a [Rakudo Star](https://rakudo.org/star) distribution, and you are not using workflow caching, those dependencies will get resolved by [zef](https://github.com/ugexe/zef) every time the workflow runs.

At the time of writing, installing Raku module dependencies can take a *long* time to run -- 5 minutes is typical. This is where a caching workflow can help. The `wf-caching.yml` workflow has been setup to use a GitHub cache to store all the modules that [zef](https://github.com/ugexe/zef) installs.

This means that the first time you run the workflow you will take the 5 minute hit, but the subsequent runs should be completed in seconds.

## Limitations of Caching

GitHub will only retain the cache for about a week if it isn't accessed.

## Support

Suggestions/patches/comments are welcomed at [Raku-GitHub-WorkFlows](https://github.com/pmqs/Raku-GitHub-Workflows)


## utf8.md
class utf8

Mutable uint8 buffer for utf8 binary data

```raku
class utf8 does Blob[uint8] is repr('VMArray') {}
```

A `utf8` is a subtype of Blob which is specifically uint8 data for holding UTF-8 encoded text.

```raku
my utf8 $b = "hello".encode;
say $b[1].fmt("0x%X"); # OUTPUT: «0x65␤»
```

# [Typegraph](# "go to top of document")[§](#typegraphrelations "direct link")

Type relations for `utf8`

raku-type-graph

utf8
utf8

Any
Any

utf8->Any

Blob
Blob

utf8->Blob

Mu
Mu

Any->Mu

Positional
Positional

Stringy
Stringy

Blob->Positional

Blob->Stringy

[Expand chart above](/assets/typegraphs/utf8.svg)


## dist_zef-sdondley-Distribution-Extension-Updater.md
[![Actions Status](https://github.com/sdondley/Distribution-Extension-Updater/actions/workflows/test.yml/badge.svg)](https://github.com/sdondley/Distribution-Extension-Updater/actions)

# NAME

Distribution::Extension::Updater - Update legacy file extensions in a Raku distribution.

# SYNOPSIS

```
# On the command line...
# upgrade all legacy extensions in a distribution directory, defaults to '.'
rdeu [ '/path/to/distro' ]

# do a dry run, don't change anything
rdeu -d

rdeu --/tests         # don't upgrade test extensions
rdeu --/mods          # don't update module extensions
rdeu --/tests --/docs # don't update tests or docs

# don't display messages to stdout
rdeu -q

# In a module...
use Distribution::Extension::Updater;
my $distro = Distribution::Extension::Updater.new('/path/to/dir');
my $bool = $distro.has-legacy-extensions;
$distro.report;

 perform the upgrade on files with the extensions passed
$distro.update-extensions( <t p6 pm pm6 pod pod6> );

```

# DESCRIPTION

Distribution::Extension::Updater searches a distribution on a local machine for legacy Perl 6 file extensions and updates them to the newer Raku extensions. The following file types and extensions can be updated:

* modules with `.pm`, `.p6`, and `.pm6` extensions
* documentation with `.pod` and `.pod6` extensions
* tests with the `.t` extension

This module also updates the META6.json file as unobtrusively as possible without reorganizing it by swapping out the `provides` section of the file with an updated version containing the new file extensions.

If the module determines that the git command is available and the distribution has a .git directory, it will `git mv` the files. Otherwise, it will move the files with Raku's `move` command.

After the module updates the extensions, the changes can be added and committed to the local git repo and then uploaded to the appropriate ecosystem manually. This module does not attempt to modify the `Changes` file.

The module does not update files located in the `resources` directory or the `.precomp` directory.

The module is designed to be run from the command line with the `rdeu` command but also provides an API for running it from a script or other module.

# COMMAND LINE OPERATION

## rdeu [ path/to/distro ]

Updates the test, documentation, and module files found in the distribution with the following extensions: `.t, .pm, .p6, .pm6, .pod, .pod6`. If no path is given, the command is run in the current directory.

### Options

#### -d|--dry-run

Performs a dry-run to give a user a chance to preview what will be changed.

#### -q|--quiet

Suppresses messages to standard output. Warnings will still be printed.

#### -h

Provides help for the `rdeu` command.

#### --/mods|modules --/documentation|docs --/tests

These three options can be used alone or in combination, can be used to prevent the updating of certain types of legacy extensions.

##### `--mods` turns off the updating of files with extension of `.p6, .pm, .pm6`.

##### `--tests` turns off the updating of files with extension of `.t`.

##### `--docs` turns off the updating of files with extension of `.pod6, .pod`.

# OBJECT CONSTRUCTION AND METHODS

As mentioned, the module can also be used from within Raku code using the following methods.

## Construction

### new(Str $d = '', :d(:$dir) = $d || '.', Bool :$quiet = False, Bool :$dry-run = False, \*%\_ ())

Creates a new D::E::U object. If no directory is provided either with a positional argument or a named argument, defaults to the current directly, '.'. Boolean arguments, `:quiet` and `:dry-run` determine whether output messages are printed and whether changes to the distribution are actually made.

## Methods

### has-legacy-extensions (\*@exts where @exts ⊆ @valid-ext)

Returns a boolean value `True` if any legacy extensions passed via @exts are found, `False` otherwise. With no arguments, will search for all known legacy extensions.

### update-extensions( @exts );

Perform the upgrade on files with the extensions passed in `@exts`. Only `.p6`, `.pm`, `.pm6`, `.t`, `.pod` and `.pod6` extensions are permitted.

### report

Get a simple report that counts the number of files found for each legacy extensions.

### get-meta

Returns the `Path::IO` object to the meta json file if found, `False` otherwise.

### has-git

Return `True` if it determines git is installed, `False` otherwisek.

### find( Str:D $ext )

Creates a key in the `%.ext` object attribute that points to a list of files with the extension supplied by `$ext`.

# AUTHOR

Steve Dondley [s@dondley.com](mailto:s@dondley.com)

# COPYRIGHT AND LICENSE

Copyright 2023 Steve Dondley

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