## classtut.md
## Chunk 1 of 2
Classes and objects

A tutorial about creating and using classes in Raku

Raku provides a rich built-in syntax for defining and using classes. It makes writing classes expressive and short for most cases, but also provides mechanisms to cover the rare corner cases.

# [A quick overview](#Classes_and_objects "go to top of document")[§](#A_quick_overview "direct link")

Let's start with an example to give an overview:

```raku
class Rectangle {
    has Int $.length = 1;
    has Int $.width = 1;

    method area(--> Int) {
        return $!length * $!width;
    }
}

my $r1 = Rectangle.new(length => 2, width => 3);
say $r1.area(); # OUTPUT: «6␤»

```

We define a new *Rectangle* class using the [class](/language/objects#Classes) keyword. It has two [attributes](#Attributes), `$!length` and `$!width` introduced with the [has](/syntax/has) keyword. Both default to `1`. Read only accessor methods are automatically generated. (Note the `.` instead of `!` in the declaration, which triggers the generation. Mnemonic: `!` resembles a closed door, `.` an open one.)

The [method](/language/objects#Methods) named `area` will return the area of the rectangle.

It is rarely necessary to explicitly write a constructor. An automatically inherited default constructor called [new](/language/objects#Object_construction) will automatically initialize attributes from named parameters passed to the constructor.

# [The Task example](#Classes_and_objects "go to top of document")[§](#The_Task_example "direct link")

As a more elaborate example the following piece of code implements a dependency handler. It showcases custom constructors, private and public attributes, methods, and various aspects of signatures. It's not a lot of code, and yet the result is interesting and useful. It will be used as an example throughout the following sections.

```raku
class Task {
    has      &!callback     is built;
    has Task @!dependencies is built;
    has Bool $.done;

    method new(&callback, *@dependencies) {
        return self.bless(:&callback, :@dependencies);
    }

    method add-dependency(Task $dependency) {
        push @!dependencies, $dependency;
    }

    method perform() {
        unless $!done {
            .perform() for @!dependencies;
            &!callback();
            $!done = True;
        }
    }
}

my $eat =
    Task.new({ say 'eating dinner. NOM!' },
        Task.new({ say 'making dinner' },
            Task.new({ say 'buying food' },
                Task.new({ say 'making some money' }),
                Task.new({ say 'going to the store' })
            ),
            Task.new({ say 'cleaning kitchen' })
        )
    );

$eat.perform();

```

# [Class](#Classes_and_objects "go to top of document")[§](#Class "direct link")

Raku, like many other languages, uses the `class` keyword to define a class. The block that follows may contain arbitrary code, just as with any other block, but classes commonly contain state and behavior declarations. The example code includes attributes (state), introduced through the `has` keyword, and behaviors, introduced through the `method` keyword.

# [Attributes](#Classes_and_objects "go to top of document")[§](#Attributes "direct link")

In the `Task` class, the first three lines inside the block all declare attributes (called *fields* or *instance storage* in other languages) using the `has` declarator. Just as a `my` variable cannot be accessed from outside its declared scope, attributes are never directly accessible from outside of the class (this is in contrast to many other languages). This *encapsulation* is one of the key principles of object oriented design.

## [Twigil `$!`](#Classes_and_objects "go to top of document")[§](#Twigil_$! "direct link")

The first declaration specifies instance storage for a callback (i.e. a bit of code to invoke in order to perform the task that an object represents):

```raku
has &!callback is built;

```

The `&` sigil indicates that this attribute represents something invocable. The `!` character is a *twigil*, or secondary sigil. A twigil forms part of the name of the variable. In this case, the `!` twigil emphasizes that this attribute is private to the class. The attribute is *encapsulated*. Private attributes will not be set by the default constructor by default, which is why we add the `is built` trait to allow just that. Mnemonic: `!` looks like a closed door.

The second declaration also uses the private twigil:

```raku
has Task @!dependencies is built;

```

However, this attribute represents an array of items, so it requires the `@` sigil. These items each specify a task that must be completed before the present one is completed. Furthermore, the type declaration on this attribute indicates that the array may only hold instances of the `Task` class (or some subclass of it).

## [Twigil `$.`](#Classes_and_objects "go to top of document")[§](#Twigil_$. "direct link")

The third attribute represents the state of completion of a task:

```raku
has Bool $.done;

```

This scalar attribute (with the `$` sigil) has a type of [`Bool`](/type/Bool). Instead of the `!` twigil, the `.` twigil is used. While Raku does enforce encapsulation on attributes, it also saves you from writing accessor methods. Replacing the `!` with a `.` both declares a private attribute and an accessor method named after the attribute. In this case, both the attribute `$!done` and the accessor method `done` are declared. It's as if you had written:

```raku
has Bool $!done;
method done() { return $!done }

```

Note that this is not like declaring a public attribute, as some languages allow; you really get *both* a private attribute and a method, without having to write the method by hand. You are free instead to write your own accessor method, if at some future point you need to do something more complex than returning the value.

## [`is rw` trait](#Classes_and_objects "go to top of document")[§](#is_rw_trait "direct link")

Note that using the `.` twigil has created a method that will provide read-only access to the attribute. If instead the users of this object should be able to reset a task's completion state (perhaps to perform it again), you can change the attribute declaration:

```raku
has Bool $.done is rw;

```

The `is rw` trait causes the generated accessor method to return a container so external code can modify the value of the attribute.

## [`is built` trait](#Classes_and_objects "go to top of document")[§](#is_built_trait "direct link")

```raku
has &!callback is built;

```

By default private attributes are not automatically set by the default constructor. (They are private after all.) In the above example we want to allow the user to provide the initial value but keep the attribute otherwise private. The `is built` trait allows to do just that.

One can also use it to do the opposite for public attributes, i.e. prevent them to be automatically initialized with a user provided value, but still generate the accessor method:

```raku
has $.done is built(False);

```

Above declaration makes sure one can't construct finished tasks, but still allow users to look if a task is done.

The `is built` trait was introduced in Rakudo version 2020.01.

## [`is required` trait](#Classes_and_objects "go to top of document")[§](#is_required_trait "direct link")

Providing a value for an attribute during initialization is optional by default. Which in the task example makes sense for all three, the `&!callback`, the `@!dependencies` and the `$.done` attribute. But lets say we want to add another attribute, `$.name`, that holds a tasks name and we want to force the user to provide a value on initialization. We can do that as follows:

```raku
has $.name is required;

```

## [Default values](#Classes_and_objects "go to top of document")[§](#Default_values "direct link")

You can also supply default values to attributes (which works equally for those with and without accessors):

```raku
has Bool $.done = False;

```

The assignment is carried out at object build time. The right-hand side is evaluated at that time, and can even reference earlier attributes:

```raku
has Task @!dependencies;
has $.ready = not @!dependencies;

```

Writable attributes are accessible through writable containers:

```raku
class a-class {
    has $.an-attribute is rw;
}
say (a-class.new.an-attribute = "hey"); # OUTPUT: «hey␤»

```

This attribute can also be accessed using the `.an-attribute` or `.an-attribute()` syntax. See also [the `is rw` trait on classes](/language/typesystem#trait_is_rw) for examples on how this works on the whole class.

# [Class variables](#Classes_and_objects "go to top of document")[§](#Class_variables "direct link")

A class declaration can also include *class variables*, declared with `my` or `our`, which are variables whose value is shared by all instances, and can be used for things like counting the number of instantiations or any other shared state. So *class variables* act similarly to *static* variables known from other programming languages. They look the same as normal (non class) lexical variables (and in fact they are the same):

```raku
class Str-with-ID is Str {
    my  $counter = 0;
    our $our-counter = 0;
    has Str $.string;
    has Int $.ID is built(False);

    submethod TWEAK() {
        $counter++;
        $our-counter++;
        $!ID = $counter;
    }

}

class Str-with-ID-and-tag is Str-with-ID {
    has Str $.tag;
}

say Str-with-ID.new(string => 'First').ID;  # OUTPUT: «1␤»
say Str-with-ID.new(string => 'Second').ID; # OUTPUT: «2␤»
say Str-with-ID-and-tag.new( string => 'Third', tag => 'Ordinal' ).ID; # OUTPUT: «3␤»
say $Str-with-ID::our-counter;        # OUTPUT: «3␤»

```

*Class variables* are shared by all subclasses, in this case `Str-with-ID-and-tag`. Additionally, when the package scope `our` declarator is used, the variable is visible via their fully qualified name (FQN), while lexically scoped `my` variables are "private". This is the exact behavior that `my` and `our` also show in non class context.

*Class variables* act similarly to *static* variables in many other programming languages.

```raku
class Singleton {
    my Singleton $instance;
    method new {!!!}
    submethod instance {
        $instance = Singleton.bless unless $instance;
        $instance;
    }
}

```

In this implementation of the *Singleton* pattern a *class variable* is used to save the instance.

```raku
class HaveStaticAttr {
    my Int $.foo = 5;
}

```

Class attributes may also be declared with a secondary sigil – in a similar manner to instance attributes – that will generate read-only accessors if the attribute is to be public. Default values behave as expected and are assigned only once.

# [Methods](#Classes_and_objects "go to top of document")[§](#Methods "direct link")

While attributes give objects state, methods give objects behaviors. Back to our `Task` example. Let's ignore the `new` method temporarily; it's a special type of method. Consider the second method, `add-dependency`, which adds a new task to a task's dependency list:

```raku
method add-dependency(Task $dependency) {
    push @!dependencies, $dependency;
}

```

In many ways, this looks a lot like a `sub` declaration. However, there are two important differences. First, declaring this routine as a method adds it to the list of methods for the current class, thus any instance of the `Task` class can call it with the `.` method call operator. Second, a method places its invocant into the special variable `self`.

The method itself takes the passed parameter – which must be an instance of the `Task` class – and `push`es it onto the invocant's `@!dependencies` attribute.

The `perform` method contains the main logic of the dependency handler:

```raku
method perform() {
    unless $!done {
        .perform() for @!dependencies;
        &!callback();
        $!done = True;
    }
}

```

It takes no parameters, working instead with the object's attributes. First, it checks if the task has already completed by checking the `$!done` attribute. If so, there's nothing to do.

Otherwise, the method performs all of the task's dependencies, using the `for` construct to iterate over all of the items in the `@!dependencies` attribute. This iteration places each item – each a `Task` object – into the topic variable, `$_`. Using the `.` method call operator without specifying an explicit invocant uses the current topic as the invocant. Thus the iteration construct calls the `.perform()` method on every `Task` object in the `@!dependencies` attribute of the current invocant.

After all of the dependencies have completed, it's time to perform the current `Task`'s task by invoking the `&!callback` attribute directly; this is the purpose of the parentheses. Finally, the method sets the `$!done` attribute to `True`, so that subsequent invocations of `perform` on this object (if this `Task` is a dependency of another `Task`, for example) will not repeat the task.

## [Private methods](#Classes_and_objects "go to top of document")[§](#Private_methods "direct link")

Just like attributes, methods can also be private. Private methods are declared with a prefixed exclamation mark. They are called with `self!` followed by the method's name. In the following implementation of a `MP3TagData` class to extract [ID3v1](https://en.wikipedia.org/wiki/ID3) metadata from an mp3 file, methods `parse-data`, `can-read-format`, and `trim-nulls` are private methods while the remaining ones are public methods:

```raku
class MP3TagData {
    has $.filename where { .IO ~~ :e };

    has Str $.title   is built(False);
    has Str $.artist  is built(False);
    has Str $.album   is built(False);
    has Str $.year    is built(False);
    has Str $.comment is built(False);
    has Int $.genre   is built(False);
    has Int $.track   is built(False);
    has Str $.version is built(False);
    has Str $.type    is built(False) = 'ID3';

    submethod TWEAK {
        with $!filename.IO.open(:r, :bin) -> $fh {
            $fh.seek(-128, SeekFromEnd);
            my $tagdata = $fh.read(128);
            self!parse-data: $tagdata;
            $fh.close;
        }
        else {
            warn "Failed to open file."
        }
    }

    method !parse-data($data) {
        if self!can-read-format($data) {
            my $offset = $data.bytes - 128;

            $!title  = self!trim-nulls: $data.subbuf($offset +  3, 30);
            $!artist = self!trim-nulls: $data.subbuf($offset + 33, 30);
            $!album  = self!trim-nulls: $data.subbuf($offset + 63, 30);
            $!year   = self!trim-nulls: $data.subbuf($offset + 93,  4);

            my Int $track-flag = $data.subbuf($offset + 97 + 28, 1).Int;
            $!track            = $data.subbuf($offset + 97 + 29, 1).Int;

            ($!version, $!comment) = $track-flag == 0 && $!track != 0
                ?? ('1.1', self!trim-nulls: $data.subbuf($offset + 97, 28))
                !! ('1.0', self!trim-nulls: $data.subbuf($offset + 97, 30));

            $!genre = $data.subbuf($offset + 97 + 30, 1).Int;
        }
    }

    method !can-read-format(Buf $data --> Bool) {
        self!trim-nulls($data.subbuf(0..2)) eq 'TAG'
    }

    method !trim-nulls(Buf $data --> Str) {
        $data.decode('utf-8').subst(/\x[0000]+/, '')
    }
}

```

To call a private method of another class, the caller has to be trusted by the callee. A trust relationship is declared with [`trusts`](/language/typesystem#trait_trusts) and the class to be trusted must already be declared. Calling a private method of another class requires an instance of that class and the fully qualified name (FQN) of the method. A trust relationship also allows access to private attributes.

```raku
class B {...}

class C {
    trusts B;
    has $!hidden = 'invisible';
    method !not-yours () { say 'hidden' }
    method yours-to-use () {
        say $!hidden;
        self!not-yours();
    }
}

class B {
    method i-am-trusted () {
        my C $c.=new;
        $c!C::not-yours();
    }
}

C.new.yours-to-use(); # the context of this call is GLOBAL, and not trusted by C
B.new.i-am-trusted();

```

Trust relationships are not subject to inheritance. To trust the global namespace, the pseudo package `GLOBAL` can be used.

# [Construction](#Classes_and_objects "go to top of document")[§](#Construction "direct link")

The object construction mechanisms described up to now suffice for most use cases. But if one actually needs to tweak object construction more than said mechanisms allow, it's good to understand how object construction works in more detail.

Raku is rather more liberal than many languages in the area of constructors. A constructor is anything that returns an instance of the class. Furthermore, constructors are ordinary methods. You inherit a default constructor named `new` from the base class [`Mu`](/type/Mu), but you are free to override `new`, as the Task example does:

```raku
method new(&callback, *@dependencies) {
    return self.bless(:&callback, :@dependencies);
}

```

## [bless](#Classes_and_objects "go to top of document")[§](#bless "direct link")

The biggest difference between constructors in Raku and constructors in languages such as C# and Java is that rather than setting up state on a somehow already magically created object, Raku constructors create the object themselves. They do this by calling the [bless](/routine/bless) method, also inherited from [`Mu`](/type/Mu). The `bless` method expects a set of named parameters to provide the initial values for each attribute.

The example's constructor turns positional arguments into named arguments, so that the class can provide a nicer constructor for its users. The first parameter is the callback (the thing which will execute the task). The rest of the parameters are dependent `Task` instances. The constructor captures these into the `@dependencies` slurpy array and passes them as named parameters to `bless` (note that `:&callback` uses the name of the variable – minus the sigil – as the name of the parameter). One should refrain from putting logic other than reformulating the parameters in the constructor, because constructor methods are not recursively called for parent classes. This is different from e.g. Java.

Declaring `new` as a `method` and not as a `multi method` prevents access to the default constructor. +So if you intend to keep the default constructor available, use `multi method new`.

## [`TWEAK`](#Classes_and_objects "go to top of document")[§](#TWEAK "direct link")

After `bless` has initialized the classes attributes from the passed values, it will in turn call `TWEAK` for each class in the inheritance hierarchy. `TWEAK` gets passed all the arguments passed to bless. This is where custom initialization logic should go.

Remember to always make `TWEAK` a [submethod](/type/Submethod) and not a normal `method`. If in a class hierarchy a class contains a `TWEAK` method (declared as a `method` instead of a `submethod`) that method is inherited to its subclass and will thus be called twice during construction of the subclass!

## [`BUILD`](#Classes_and_objects "go to top of document")[§](#BUILD "direct link")

It is possible to disable the automatic attribute initialization and perform the initialization of attributes oneself. To do so one needs to write a custom `BUILD` submethod. There are several edge cases one needs to be aware of and take into account though. This is detailed in the [Object Construction Reference](/language/objects#Object_construction). Because of the difficulty of using `BUILD`, it is recommended to only make use of it when none of the other approaches described above suffices.

# [Destruction](#Classes_and_objects "go to top of document")[§](#Destruction "direct link")

Raku is a garbage collecting language. This means that one usually doesn't need to care about cleaning up objects, because Raku does so automatically. Raku does not give any guarantees as to when it will clean up a given object though. It usually does a cleanup run only if the runtime needs the memory, so we can't rely on when it's going to happen.

To run custom code when an object is cleaned up one can use the `DESTROY` submethod. It can for example be used to close handles or supplies or delete temporary files that are no longer going to be used. As garbage collection can happen at arbitrary points during the runtime of our program, even in the middle of some totally unrelated piece of code in a different thread, we must make sure to not assume any context in our `DESTROY` submethod.

```raku
my $in_destructor = 0;

class Foo {
    submethod DESTROY { $in_destructor++ }
}

my $foo;
for 1 .. 6000 {
    $foo = Foo.new();
}

say "DESTROY called $in_destructor times";

```

This might print something like `DESTROY called 5701 times` and possibly only kicks in after we have stomped over former instances of `Foo` a few thousand times. We also can't rely, on the order of destruction.

Same as `TWEAK`: Make sure to always declare `DESTROY` as a `submethod`.

# [Consuming our class](#Classes_and_objects "go to top of document")[§](#Consuming_our_class "direct link")

After creating a class, you can create instances of the class. Declaring a custom constructor provides a simple way of declaring tasks along with their dependencies. To create a single task with no dependencies, write:

```raku
my $eat = Task.new({ say 'eating dinner. NOM!' });

```

An earlier section explained that declaring the class `Task` installed a type object in the namespace. This type object is a kind of "empty instance" of the class, specifically an instance without any state. You can call methods on that instance, as long as they do not try to access any state; `new` is an example, as it creates a new object rather than modifying or accessing an existing object.

Unfortunately, dinner never magically happens. It has dependent tasks:

```raku
my $eat =
    Task.new({ say 'eating dinner. NOM!' },
        Task.new({ say 'making dinner' },
            Task.new({ say 'buying food' },
                Task.new({ say 'making some money' }),
                Task.new({ say 'going to the store' })
            ),
            Task.new({ say 'cleaning kitchen' })
        )
    );

```

Notice how the custom constructor and the sensible use of whitespace makes task dependencies clear.

Finally, the `perform` method call recursively calls the `perform` method on the various other dependencies in order, giving the output:

｢output｣ without highlighting

```

```

making some money
going to the store
buying food
cleaning kitchen
making dinner
eating dinner. NOM!

```

```

## [A word on types](#Classes_and_objects "go to top of document")[§](#A_word_on_types "direct link")

Declaring a class creates a new *type object* which, by default, is installed into the current package (just like a variable declared with `our` scope). This type object is an "empty instance" of the class. For example, types such as [`Int`](/type/Int) and [`Str`](/type/Str) refer to the type object of one of the Raku built-in classes. One can call methods on these type objects. So there is nothing special with calling the `new` method on a type object.

You can use the `.DEFINITE` method to find out if what you have is an instance or a type object:

```raku
say Int.DEFINITE; # OUTPUT: «False␤» (type object)
say 426.DEFINITE; # OUTPUT: «True␤»  (instance)

class Foo {};
say Foo.DEFINITE;     # OUTPUT: «False␤» (type object)
say Foo.new.DEFINITE; # OUTPUT: «True␤»  (instance)

```

In function signatures one can use so called type "smileys" to only accept instances or type objects:

```raku
multi foo (Int:U) { "It's a type object!" }
multi foo (Int:D) { "It's an instance!"   }
say foo Int; # OUTPUT: «It's a type object!␤»
say foo 42;  # OUTPUT: «It's an instance!␤»

```

# [Inheritance](#Classes_and_objects "go to top of document")[§](#Inheritance "direct link")

Object Oriented Programming provides the concept of inheritance as one of the mechanisms for code reuse. Raku supports the ability for one class to inherit from one or more classes. When a class inherits from another class it informs the method dispatcher to follow the inheritance chain to look for a method to dispatch. This happens both for standard methods defined via the `method` keyword and for methods generated through other means, such as attribute accessors.

```raku
class Employee {
    has $.salary;
}

class Programmer is Employee {
    has @.known_languages is rw;
    has $.favorite_editor;

    method code_to_solve( $problem ) {
        return "Solving $problem using $.favorite_editor in "
        ~ $.known_languages[0];
    }
}

```

Now, any object of type Programmer can make use of the methods and accessors defined in the Employee class as though they were from the Programmer class.

```raku
my $programmer = Programmer.new(
    salary => 100_000,
    known_languages => <Raku Perl Erlang C++>,
    favorite_editor => 'vim'
);

say $programmer.code_to_solve('halting problem'),
    " will get \$ {$programmer.salary()}";
# OUTPUT: «Solving halting problem using vim in Raku will get $100000␤»

```

## [Overriding inherited methods](#Classes_and_objects "go to top of document")[§](#Overriding_inherited_methods "direct link")

Classes can override methods and attributes defined by parent classes by defining their own. The example below demonstrates the `Baker` class overriding the `Cook`'s `cook` method.

```raku
class Cook is Employee {
    has @.utensils  is rw;
    has @.cookbooks is rw;

    method cook( $food ) {
        say "Cooking $food";
    }

    method clean_utensils {
        say "Cleaning $_" for @.utensils;
    }
}

class Baker is Cook {
    method cook( $confection ) {
        say "Baking a tasty $confection";
    }
}

my $cook = Cook.new(
    utensils  => <spoon ladle knife pan>,
    cookbooks => 'The Joy of Cooking',
    salary    => 40000
);

$cook.cook( 'pizza' );       # OUTPUT: «Cooking pizza␤»
say $cook.utensils.raku;     # OUTPUT: «["spoon", "ladle", "knife", "pan"]␤»
say $cook.cookbooks.raku;    # OUTPUT: «["The Joy of Cooking"]␤»
say $cook.salary;            # OUTPUT: «40000␤»

my $baker = Baker.new(
    utensils  => 'self cleaning oven',
    cookbooks => "The Baker's Apprentice",
    salary    => 50000
);

$baker.cook('brioche');      # OUTPUT: «Baking a tasty brioche␤»
say $baker.utensils.raku;    # OUTPUT: «["self cleaning oven"]␤»
say $baker.cookbooks.raku;   # OUTPUT: «["The Baker's Apprentice"]␤»
say $baker.salary;           # OUTPUT: «50000␤»

```

Because the dispatcher will see the `cook` method on `Baker` before it moves up to the parent class the `Baker`'s `cook` method will be called.

To access methods in the inheritance chain, use [re-dispatch](/language/functions#Re-dispatching) or the [MOP](/type/Metamodel/ClassHOW#method_can).

## [Multiple inheritance](#Classes_and_objects "go to top of document")[§](#Multiple_inheritance "direct link")

As mentioned before, a class can inherit from multiple classes. When a class inherits from multiple classes the dispatcher knows to look at both classes when looking up a method to search for. Raku uses the [C3 algorithm](https://en.wikipedia.org/wiki/C3_linearization) to linearize multiple inheritance hierarchies, which is better than depth-first search for handling multiple inheritance.

```raku
class GeekCook is Programmer is Cook {
    method new( *%params ) {
        push( %params<cookbooks>, "Cooking for Geeks" );
        return self.bless(|%params);
    }
}

my $geek = GeekCook.new(
    books           => 'Learning Raku',
    utensils        => ('stainless steel pot', 'knife', 'calibrated oven'),
    favorite_editor => 'MacVim',
    known_languages => <Raku>
);

$geek.cook('pizza');
$geek.code_to_solve('P =? NP');

```

Now all the methods made available to the Programmer and the Cook classes are available from the GeekCook class.

While multiple inheritance is a useful concept to know and occasionally use, it is important to understand that there are more useful OOP concepts. When reaching for multiple inheritance it is good practice to consider whether the design wouldn't be better realized by using roles, which are generally safer because they force the class author to explicitly resolve conflicting method names. For more information on roles, see [Roles](/language/objects#Roles).

## [`also`](#Classes_and_objects "go to top of document")[§](#The_also_declarator "direct link")

Classes to be inherited from can be listed in the class declaration body by prefixing the `is` trait with `also`. This also works for the role composition trait `does`.

```raku
class GeekCook {
    also is Programmer;
    also is Cook;
    # ...
}

role A {};
role B {};
class C {
    also does A;
    also does B;
    # ...
}

```

# [Introspection](#Classes_and_objects "go to top of document")[§](#Introspection "direct link")

Introspection is the process of gathering information about some objects in your program, not by reading the source code, but by querying the object (or a controlling object) for some properties, such as its type.

Given an object `$o` and the class definitions from the previous sections, we can ask it a few questions:

```raku
my Programmer $o .= new;
if $o ~~ Employee { say "It's an employee" };
say $o ~~ GeekCook ?? "It's a geeky cook" !! "Not a geeky cook";
say $o.^name;
say $o.raku;
say $o.^methods(:local)».name.join(', ');

```

The output might look like this:

｢output｣ without highlighting

```

```

It's an employee
Not a geeky cook
Programmer
Programmer.new(known_languages => ["Perl", "Python", "Pascal"],
        favorite_editor => "gvim", salary => "too small")
code_to_solve, known_languages, favorite_editor

```

```

The first two tests each smartmatch against a class name. If the object is of that class, or of an inheriting class, it returns `True`. So the object in question is of class `Employee` or one that inherits from it, but not `GeekCook`.

The call `$o.^name` tells us the type of `$o`; in this case `Programmer`.

`$o.raku` returns a string that can be executed as Raku code, and reproduces the original object `$o`. While this does not work perfectly in all cases, it is very useful for debugging simple objects. [[1]](#fn1)

The syntax of calling a method with `.^` instead of a single dot means that it is actually a method call on its *metaclass*, which is a class managing the properties of the `Programmer` class – or any other class you are interested in. This metaclass enables other ways of introspection too:

```raku
say $o.^attributes.join(', ');
say $o.^parents.map({ $_.^name }).join(', ');

```

Finally `$o.^name` calls the `name` method on the metaobject, which unsurprisingly returns the class name.

Given an object `$mp3` and the `MP3TagData` class definition from the section [Private methods](/language/classtut#Private_methods), we can inquire about its public methods with `.^methods`:

```raku
my $mp3 = MP3TagData.new(filename => 'football-head.mp3');
say $mp3.^methods(:local);
# OUTPUT: (TWEAK filename title artist album year comment genre track version
# type Submethod+{is-hidden-from-backtrace}.new)

```

`$mp3.^methods(:local)` produces a list of [`Method`](/type/Method)s that can be called on `$mp3`. The `:local` named argument limits the returned methods to those defined in the `MP3TagData` class and excludes the inherited methods; `MP3TagData` inherits from no class, so providing `:local` makes no difference.

To check if a type object (or an instance object) implements a certain public method, use the [`.^find-method`](/routine/find_method) metamethod, which returns the method object if it exists. Otherwise, it returns [`Mu`](/type/Mu).

```raku
say $mp3.^find_method('name');   # OUTPUT: «(Mu)␤»
say $mp3.^find_method('artist'); # OUTPUT: «artist␤»

```

Type objects can also be introspected for its private methods. However, public and private methods don't use the same APIs, and thus different metamethods must be used: [`.^private_methods`](/routine/private_methods) and [`.^find_private_method`](/routine/find_private_method).

```raku
say $mp3.^private_methods;                     # OUTPUT: «(parse-data can-read-format trim-nulls)␤»
say $mp3.^find_private_method('parse-data');   # OUTPUT: «parse-data␤»
say $mp3.^find_private_method('remove-nulls'); # OUTPUT: «(Mu)␤»

```

Introspection is very useful for debugging and for learning the language and new libraries. When a function or method returns an object you don't know about, by finding its type with `.^name`, seeing a construction recipe for it with `.raku`, and so on, you'll get a good idea of what its return value is. With `.^methods`, you can learn what you can do with the class.

But there are other applications too. For instance, a routine that serializes objects to a bunch of bytes needs to know the attributes of that object, which it can find out via introspection.

## [Overriding default gist method](#Classes_and_objects "go to top of document")[§](#Overriding_default_gist_method "direct link")

Some classes might need their own version of `gist`, which overrides the terse way they are printed when called to provide a default representation of the class. For instance, [exceptions](/language/exceptions#Uncaught_exceptions) might want to write just the `payload` and not the full object so that it is clearer what to see what's happened. However, this isn't limited to exceptions; you can do that with every class:

```raku
class Cook


## classtut.md
## Chunk 2 of 2
 {
    has @.utensils  is rw;
    has @.cookbooks is rw;

    method cook( $food ) {
        return "Cooking $food";
    }

    method clean_utensils {
        return "Cleaning $_" for @.utensils;
    }

    multi method gist(Cook:U:) { '⚗' ~ self.^name ~ '⚗' }
    multi method gist(Cook:D:) {
        '⚗ Cooks with ' ~ @.utensils.join( " ‣ ") ~ ' using '
          ~ @.cookbooks.map( "«" ~ * ~ "»").join( " and ") }
}

my $cook = Cook.new(
    utensils => <spoon ladle knife pan>,
    cookbooks => ['Cooking for geeks','The French Chef Cookbook']);

say Cook.gist; # OUTPUT: «⚗Cook⚗»
say $cook.gist; # OUTPUT: «⚗ Cooks with spoon ‣ ladle ‣ knife ‣ pan using «Cooking for geeks» and «The French Chef Cookbook»␤»

```

Usually you will want to define two methods, one for the class and another for class instances; in this case, the class method uses the alembic symbol, and the instance method, defined below it, aggregates the data we have on the cook to show it in a narrative way.

## [A practical introspection example](#Classes_and_objects "go to top of document")[§](#A_practical_introspection_example "direct link")

When one creates a new class, it is sometimes useful to have informative (and safe) introspection accessible more easily as a public method. For example, the following class is used to hold attributes for a record row in a CSV spreadsheet with a header row defining its field (attribute) names.

```raku
unit class CSV-Record;
#| Field names and values for a CSV row
has $last;
has $first;
#...more fields (attributes)...

method fields(--> List) {
    #| Return a list of the the attribute names (fields)
    #| of the class instance
    my @attributes = self.^attributes;
    my @names;
    for @attributes -> $a {
        my $name = $a.name;
        # The name is prefixed by its sigil and twigil
        # which we don't want
        $name ~~ s/\S\S//;
        @names.push: $name;
    }
    @names
}

method values(--> List) {
    #| Return a list of the values for the attributes
    #| of the class instance
    my @attributes = self.^attributes;
    my @values;
    for @attributes -> $a {
        # Syntax is not obvious
        my $value = $a.get_value: self;
        @values.push: $value;
    }
    @values
}

```

We use it with a simple CSV file with contents:

｢csv｣ without highlighting

```

```

last,   first #...more fields...
Wall,   Larry
Conway, Damian

```

```

Load the first record and show its contents:

```raku
my $record = CSV-Record.new: :$last, :$first;
say $record.fields.raku; # OUTPUT: «["last", "first"]␤»
say $record.values.raku; # OUTPUT: «["Wall", "Larry"]␤»

```

Note that practically we would have designed the class so that it has the `fields` list as a constant since its values are the same for all class objects:

```raku
constant @fields = <last first>;
method fields(--> List) {
    @fields
}

```

Downsides of using the introspective method for attribute names include slightly more processing time and power and the probable need to remove the sigil and twigil for public presentation.

1 [[↑]](#fnret1) For example, closures cannot easily be reproduced this way; if you don't know what a closure is don't worry. Also current implementations have problems with dumping cyclic data structures this way, but they are expected to be handled correctly by `.raku` at some point.


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

# NAME

Number::Bytes::Human - Convert byte count into an easy to read format

# SYNOPSIS

```
# Functional interface
use Number::Bytes::Human :functions;
my $size = format-bytes 1024;   # '1K'
my $bytes = parse-bytes '1.0K'; # 1024

# OO Interface
my Number::Bytes::Human;
my $human = Number::Bytes::Human.new;

my $size = $human.format(1024);   # '1K'
my $bytes = $human.parse('1.0K'); # 1024

```

# DESCRIPTION

This is the Raku re-write of CPAN's `Number::Bytes::Human` module. Special thanks to the original author: Adriano R. Ferreira.

The `Number::Bytes::Humani` module converts large numbers of bytes into a more human friendly format, e.g. '15G'. The functionality of this module will be similar to the `-h` switch on Unix commands like `ls`, `du`, and `df`.

Currently the module rounds to the nearest whole unit.

From the FreeBSD man page of df: <http://www.freebsd.org/cgi/man.cgi?query=df>

```
"Human-readable" output.  Use unit suffixes: Byte, Kilobyte,
Megabyte, Gigabyte, Terabyte and Petabyte in order to reduce the
number of digits to four or fewer using base 2 for sizes.

byte      B
kilobyte  K = 2**10 B = 1024 B
megabyte  M = 2**20 B = 1024 * 1024 B
gigabyte  G = 2**30 B = 1024 * 1024 * 1024 B
terabyte  T = 2**40 B = 1024 * 1024 * 1024 * 1024 B

petabyte  P = 2**50 B = 1024 * 1024 * 1024 * 1024 * 1024 B
exabyte   E = 2**60 B = 1024 * 1024 * 1024 * 1024 * 1024 * 1024 B
zettabyte Z = 2**70 B = 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 B
yottabyte Y = 2**80 B = 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 B

```

# AUTHOR

Douglas L. Jenkins

# COPYRIGHT AND LICENSE

Copyright 2016 - 2017 Douglas L. Jenkins

Copyright 2024 Raku Community

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


## dist_github-jaffa4-Dependency-Sort.md
# Dependency-Sort

This is a Perl6 module. It serialises a list of dependencies or it performs a topological sort on directed graph.

Example:

```
my %h; # this represents one node
my %g;
%h<itemid> = 1; # itemid should be unique for each rach
%g<itemid> = 2;
%h<name>   = '1';
%g<name>   = '2';

my %j  = ( "itemid", 3, "name", 3 );
my %j4 = ( "itemid", 4, "name", 4 );

my $s = Dependency::Sort.new();

$s.add_dependency( %h, %g ); # this means %h depends on %g
$s.add_dependency( %h, %j );

$s.add_dependency( %j, %j4 );
$s.add_dependency( %j, %g );

$s.add_dependency( %g, %j );

if !$s.serialise  # returns false if there is an error
{
  die $s.error_message; # the error message, meaning circular reference
}
else
{ # list of nodes in result... starting with independent ones.. then less dependent ones
  say $s.result.perl; # prints independent ones first
}

```


## dist_zef-jnthn-HTTP-HPACK.md
# HTTP::HPACK

[![Build Status](https://travis-ci.org/jnthn/p6-http-hpack.svg?branch=master)](https://travis-ci.org/jnthn/p6-http-hpack)

## Synopsis

Decoding:

```
my $decoder = HTTP::HPACK::Decoder.new;
my @headers = $decoder.decode-headers($buf);
say "{.name}: {.value} ({.indexing})" for @headers;

```

Encoding:

```
my @headers =
    HTTP::HPACK::Header.new(
        name  => ':method',
        value => 'GET'
    ),
    HTTP::HPACK::Header.new(
        name     => 'password',
        value    => 'correcthorsebatterystaple',
        indexing => HTTP::HPACK::Indexing::NeverIndexed
    );
my $encoder = HTTP::HPACK::Encoder.new;
my $buf = $encoder.encode-headers(@headers);

```

## Description

HPACK is the HTTP/2 header compression algorithm. This module implements encoding
(compression) and decoding (decompression) of the HPACK format, as specified in
RFC 7541. A HTTP/2 connection will typically have an instance of the decoder (to
decompress incoming headers) and an instance of the encoder (to compress outgoing
headers).

## Notes on specific features

### Huffman compression

Decoding of headers compressed using the Huffman codes (set out in the RFC) takes
place automatically. By default, the encoder will not apply Huffman compression.
To enable this, construct it with the `huffman` option set to `True`:

```
my $encoder = HTTP::HPACK::Encoder.new(:huffman);

```

### Dynamic table management

The dynamic table size can be limited by passing the `dynamic-table-limit` option
when constructing either the encoder or decoder:

```
my $decoder = HTTP::HPACK::Decoder.new(dynamic-table-limit => 256);

```

It is also possible to introspect the current dynamic table size:

```
say $decoder.dynamic-table-size;

```

The size is computed according to the algorithm in RFC 7541 Section 4.1.

## Thread safety

Instances of HTTP::HPACK::Header are immutable and so safe to share and access
concurrently. Instances of HTTP::HPACK::Decoder and HTTP::HPACK::Encoder are
stateful (as a result of the dynamic table), and so a given instance may not be
used concurrently. This is not a practical problem, since headers may only be
processed in the order they are being received or transmitted anyway.

## Known issues

* The Huffman code termination handling has not been validated to be completely
  up to specification, and so may fail to signal errors in some cases where the
  Huffman code is terminated in a bogus way.


## dist_zef-witawayar-Asserter.md
## Asserter

Be assertive in the form `assert EXPR, MESSAGE?`

```
use Asserter;

# Without a custom message, expression itself and its value are reported
my $val = Empty;
assert $val;
#= Assertion failed: `$val` is not true; it evaluates to `Empty`

# You can say what you like
assert $val.&prime-factors.pick.is-prime, "mathematics gone wrong";
#= Assertion failed: mathematics gone wrong

# If condition is truthful, short-circuits, i.e., MESSAGE is not evaluated
assert True, destroy-the-universe();
#= Universe is still fine at this point

# The error is CATCHable as:
{
    CATCH {
        when X::Assertion {
            ...
        }
    }
    assert ...;
}

# If more than 2 things are supplied, it errs in compile time
assert $val, "message", "and some more";
#`[
===SORRY!=== Error while compiling some/file.raku
That's too assertive; expected 1 or 2 things, got 3
at some/file.raku:5
------> assert $val, "message", "and some more"⏏;
]

```

### .WHAT, .WHY, .HOW

Sometimes you want to make sure something is something in the program flow; `assert` does
that for you, like in C, Java, Python and others. It compiles to something like `die MESSAGE
unless EXPR`, which a programmer could be lazy enough not to write in full. So this module
refines the main slang to do that with the word `assert`.

#### Installation

Using [pakku](https://github.com/hythm7/Pakku):

```
pakku add Asserter

```


## dist_cpan-VRURG-Async-Workers.md
# NAME

`Async::Workers` - Asynchronous threaded workers

# SYNOPSIS

```
use Async::Workers;

my $wm = Async::Workers.new( :max-workers(5) );

for 1..10 -> $n {
    $wm.do-async: {
        sleep 1.rand;
        say "Worker #$n";
    }
}

await $wm;

```

# DESCRIPTION

This module provides an easy way to execute a number of jobs in parallel while allowing to keep the resources consumed by your code under control.

Both OO and procedural interfaces are provided.

## Reliability

This module has been tested by running 20k repetitions of it's test suite using 56 parallel processes. This doesn't prove there're no bugs, but what can be told for certain is that within the tested scenarios the robustness is high enough.

## Terminology

* *job* is what gets executed. Depending on context, a *job* could be an instance of `Async::Workers::Job` class, or a user provided code object.
* *worker* is an instance of `Async::Workers::Worker` class. It is controlling a dedicated thread in which the job code is ran.
* *worker manager* or just *manager* is an instance of `Async::Workers` class which controls the execution flow and manages workers.

## How it works.

The goal is achieved by combining a *queue of jobs* and a number of pre-spawned threads controlled by *workers*. A job is picked from the queue by a currently unoccupied worker and the code object associated with it is invoked. Since the number of workers is limited it is easier to predict and plan CPU usage.

Yet, it is still possible to over-use memory and cause heavy swapping or even overflows in cases when there is too many jobs are produced and an average one takes longer to complete than it is needed to generate a new one. To provide some control over this situation one can define *hi* and *lo* thresholds on the queue size. When the queue contains as many jobs, as defined by the *hi* threshold, `do-async` method blocks upon receiving a new job request and unblocks only when the queue shortens down to its *lo* threshold.

The worker manager doesn't start workers until the first job is sent to the queue. It is also possible to shutdown all workers if they're no longer needed.

Some internal events are reported with messages from `Async::Workers::Msg`. See the `on_msg` method below.

# ATTRIBUTES

## `max-workers`

Maximum number of workers. Defaults to `$*KERNEL.cpu-cores`.

## `max-jobs`

Set the maximum number of jobs a worker should process before stopping and letting the manager to spawn a new one. The functionality is not activated if the attribute is left undefined.

## `lo-threshold`, `hi-threshold`

Low and high thresholds of the queue size.

## `queued`

Current queue size. If the queue has been blocked due to reaching `hi-threshold` then jobs awaiting for unblock are not counted toward this value.

## `running`

The number of currently occupied workers.

## `completed`

A `Promise` which is kept when manager completes all jobs after transitioning into *shutdown* state. When this happens the job queue is closed and all workers are requested to stop. Submission of a new job with `do-async` at this point will re-vivify the queue and return the manager into working state.

In case of an internal failure the promise will be broken with an exception.

## `empty`

A `Promise` which is kept each time the queue gets emptied. Note that the initially empty queue is not reflected with this attribute. Only when the queue contained at least one element and then went down to zero length this promise is kept. In other words, it happens when `Async::Workers::Msg::Queue::Empty` is emitted.

Immediately after being kept the attribute gets replaced with a fresh `Promise`. So that the following example will finish only if the queue has been emptied twice:

```
await $wm.empty;
await $wm.empty;

```

## `quiet`

If set to *True* then no exceptions thrown by jobs are reported. In this case it is recommended to monitor messages for `Async::Workers::Msg::Job::Died`.

# METHODS

## `do-async( &code, |params --> Async::Workers::Job )`

Takes a `&code` object and wraps it into a job object. `params` are passed to `&code` when it gets executed.

This method blocks if `hi-threshold` is defined and the queue size has reached the limit.

If no error happens then the method returns an `Async::Workers::Job` instance. Otherwise it may throw either `X::Manager::Down` if the manager is in `shutdown` or `completed` status; or it may throw `X::Manager::NoQueue` if somehow the job queue has not been initialized properly.

## `shutdown`

Switches the manager into *shutdown* state and closes the job queue. Since the queue might still contain some incomplete jobs it is likely to take some time until the `completed` promise gets kept. Normally it'd be helpful to `await` for the manager:

```
my $wm = Async::Workers.new(...);
...
$wm.shutdown;
await $wm;

```

In this case the execution blocks until the job queue is emptied. Note that at this point `completed` might still not been fulfilled because workers are being shutting down in the meanwhile.

## `workers`

Returns the number of started workers.

## `workers( UInt $num )`

Sets the maximum number of workers (`max-workers` attribute). Can be used at any time without shutting down the manager:

```
$wm = Async::Worker.new: :max-workers(20);
$wm.do-async: &job1 for ^$repetitions;
$wm.workers($wm.workers - 5);
$wm.do-async: &job2 for ^$repetitions;

```

If user increases the number of workers then as many additional ones are started as necessary.

On the contrary, if the number of workers is reduced then as many of them are requested to stop as needed to meet user's demand. **Note** that this is done by injecting special jobs. It means that for a really long queue it may take quite a time before the extra workers receive the stop command. This behaviour may change in the future.

## `set-threshold( UInt :$lo, Num :$hi )`

Dynamically sets high and low queue thresholds. The high might be set to `Inf` to define unlimited queue size. Note that this would translate into undefined value of `hi-threshold` attribute.

## `on_msg( &callback )`

Submits a `Async::Workers::Msg` message object to user code passed in `&callback`. Internally this method does tapping on a message and returns a resulting `Tap` object (see documentation on `Supply`).

The following messages can currently be emitted by the manager (names are shortened to not include `Async::Workers::Msg::` prefix):

* `Shutdown` - when the manager is switched into shutdown state
* `Complete` - when manager completed all jobs and shut down all workers
* `Exception` - when an internal failure is intercepted; the related exception object is stored in attribute `exception`
* `Worker` - not emitted, a base class for other `Worker` messages. Defines attribute `worker` which contains the worker object
* `Worker::Started` - when a new worker thread has started
* `Worker::Complete` - when a worker finishes
* `Worker::Died` - when a worker throws. `exception` attribute will then contain the exception thrown. This message normally should not be seen as it signals about an internal error.
* `Queue` – not emitted, a base class for other `Queue` messages. Defines attribute `size` which contains queue size at the moment when message was emitted.
* `Queue::Inc` - queue size inceased; i.e. a new job submitted. Note that if the queue has reached the *hi* threshold then a job passed to `do-async` doesn't make it into the queue and thus no message is emitted until the queue is unblocked.
* `Queue::Dec` – a job has finished and the queue size is reduced
* `Queue::Full` - *hi* threshold is reached
* `Queue::Low` - queue size reduced down to *lo* threshold
* `Queue::Empty` – the queue was emtied
* `Job` – not emitted, a parent class of job-related messages. Defines `job` attribute which holds a `Async::Workers::Job` object.
* `Job::Enter` - emitted right before a worker is about to invoke a job
* `Job::Complete` – emitted right after a job finishes
* `Job::Died` – when a job throws. `exception` attribute contains the exception object.

# HELPER SUBS

## `stop-worker($rc?, :$soft = False)`

Bypasses to the current worker `stop` method.

If called from within a job code it would cause the worker controlling the job to stop. If this would reduce the number of workers to less than `max-workers` then the manager will spawn as many new ones as needed:

```
$wm.do-async: {
    if $something-went-wrong {
        stop-worker
    }
}

```

Note that the job would be stopped too, unless `:soft` parameter is used. In this case both the job and its worker will be allowed to complete. The worker will stop after the job is done.

# PROCEDURAL

Procedural interface hides a singleton object behind it. The following subs are exported by the module:

## `async-workers( |params --> Async::Workers:D )`

Returns the singleton object. Creates it if necessary. If supplied with parameters they're passed to the constructor. If singleton is already created then the parameters are ignored.

## `do-async`

Bypasses to the corresponding method on the singleton.

```
do-async {
    say "My task";
}

```

## `shutdown-workers`

Bypasses to `shutdown` on the singleton.

# AUTHOR

Vadim Belman [vrurg@cpan.org](mailto:vrurg@cpan.org)

# LICENSE

Artistic License 2.0

See the *LICENSE* file in this distribution.


## dist_zef-antononcube-Math-DistanceFunctions-Native.md
# Math::DistanceFunctions::Native

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

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

Raku package with distance functions implemented in C.
Apple's Accelerate library is used if available.

The primary motivation for making this library is to have fast sorting and nearest neighbors computations
over collections of LLM-embedding vectors.

---

## Usage examples

### Regular vectors

Make a large (largish) collection of large vectors and find Euclidean distances over them:

```
use Math::DistanceFunctions::Native;

my @vecs = (^1000).map({ (^1000).map({1.rand}).cache.Array }).Array;
my @searchVector = (^1000).map({1.rand});

my $start = now;
my @dists = @vecs.map({ euclidean-distance($_, @searchVector)});
my $tend = now;
say "Total time of computing {@vecs.elems} distances: {round($tend - $start, 10 ** -6)} s";
say "Average time of a single distance computation: {($tend - $start) / @vecs.elems} s";

```

```
# Total time of computing 1000 distances: 0.63326 s
# Average time of a single distance computation: 0.0006332598499999999 s

```

### `CArray` vectors

Use `CArray` vectors instead:

```
use NativeCall;
my @cvecs = @vecs.map({ CArray[num64].new($_) });
my $cSearchVector = CArray[num64].new(@searchVector);

$start = now;
my @cdists = @cvecs.map({ euclidean-distance($_, $cSearchVector)});
$tend = now;
say "Total time of computing {@cvecs.elems} distances: {round($tend - $start, 10 ** -6)} s";
say "Average time of a single distance computation: {($tend - $start) / @cvecs.elems} s";

```

```
# Total time of computing 1000 distances: 0.002994 s
# Average time of a single distance computation: 2.994124e-06 s

```

I.e., we get ≈ 200 times speed-up using `CArray` vectors and the functions of this package.

### Edit distance

The loading of this package automatically loads the (C-implemented) function `edit-distance` of
["Math::DistanceFunctions::Edit"](https://github.com/antononcube/Raku-Math-DistanceFunctions-Edit).
Here is an example usage:

```
edit-distance('racoon', 'raccoon')

```

```
# 1

```


## dist_github-alabamenhu-Test-Inline.md
# Test::Inline

An lightweight Raku module allowing tests anywhere in modules (thus potentially enabling access to implementation details).

This module was inspired by an [r/rakulang post](https://www.reddit.com/r/rakulang/comments/ih8tc9) by **codesections**, who expressed a desire to have test files be more closely connected with their associated modules.
While this technique doesn't remove the code from distribution versions, it *does* allow for testing *inside of* modules/classes/etc.

To use, simply add the trait `is test` to a `Sub` anywhere in your code.
There is really only a single restriction

* *The `Sub` must take no arguments*
  (Use dynamic variables to pass data if you need to)

Here is a somewhat contrived example that should show nicely how it can be integrated.

```
unit module Rectangle;

use Test::Inline;

has Point $.a; # bottom left
has Point $.b; # top right

sub calculate-area($x, $y) {     $x * $y }
sub distance(      $a, $b) { abs $a - $b }

method area {
  calculate-area
    distance($!a.x, $!b.x),
    distance($!a.y, $!b.y)
}

method overlap(Rectangle $other) { ... }

sub t-distance is test {
  use Test;
  is distance( 2,4), 2;
  is distance(-2,4), 6;
  ...
}

sub t-area is test {
  use Test;
  is calculate-area(1,3),  3;
  is calculate-area(8,3), 24;
  ...
}

```

This marks `t-area` and `t-distance` as special subs that contains tests.
Because they are inside of `Rectangle`, they can access its lexically scoped subs or variables, which a normal test file cannot.
Each test sub can contain or do whatever it wants but it's *strongly* recommended to `use Test` and take advantage of its routines, like in the example.
Each test sub is treated as a subtest (ha!) of the package it's included in.

To actually run the tests, just add the option `:testing` to import in the special sub `inline-testing` in a test file.
When this is called, it will cycle through all subs tagged as tests, grouping them by packages:

```
use Test;
use Test::Inline :testing;

# The first step is to 'use' each module that contains
# testable subs.  Nothing else needs to be done here.
use Rectangle;   # load any modules with
use Circle;      # subs that have the
use Trapezoid;   # 'is test' trait

# Then, initiate the inline testing
# (counts as a single test with subtests)
inline-testing;

# Conclude testing in the .t file
done-testing();

```

## Version history

* **v0.1**
  * Initial release
  * All features should work
  * If no issues are found, I'll bump version to 1.0 at the end of 2020.

## License and Copyright

Licensed under the Artist License 2.0.
© 2020 Matthew Stephen Stuckwisch


## dist_cpan-UFOBAT-I18N-LangTags.md
[![Build Status](https://travis-ci.org/ufobat/p6-I18N-LangTags.svg?branch=master)](https://travis-ci.org/ufobat/p6-I18N-LangTags)

# NAME

I18N::LangTags - ported from Perl5

# SYNOPSIS

```
use I18N::LangTags;

```

# DESCRIPTION

Language tags are a formalism, described in RFC 3066 (obsoleting 1766), for declaring what language form (language and possibly dialect) a given chunk of information is in.

This library provides functions for common tasks involving language tags as they are needed in a variety of protocols and applications.

Please see the "See Also" references for a thorough explanation of how to correctly use language tags.

# FUNCTIONS

* `is_language_tag(Str:D $lang1 --> Bool)`

  Returns `True` if `$lang1` is a formally valid language tag.

  ```
  is_language_tag("fr")              # is True
  is_language_tag("x-jicarilla")     # is False
  # Subtags can be 8 chars long at most -- 'jicarilla' is 9

  is_language_tag("sgn-US")          # is True
  # That's American Sign Language

  is_language_tag("i-Klikitat")      # is True
  # True without regard to the fact noone has actually
  # registered Klikitat -- it's a formally valid tag

  is_language_tag("fr-patois")       # is True
  # Formally valid -- altho descriptively weak!

  is_language_tag("Spanish")         # is False
  is_language_tag("french-patois")   # is False
  # No good -- first subtag has to be 2 or 3 chars long -- see RFC3066

  is_language_tag("x-borg-prot2532") # is True
  # Yes, subtags can contain digits, as of RFC3066

  ```
* `extract_language_tags(Str:D $text --> Seq)`

  Returns a list of whatever looks like formally valid language tags in `$text`. Not very smart, so don't get too creative with what you want to feed it.

  ```
  extract_language_tags("fr, fr-ca, i-mingo")
  # returns:   ('fr', 'fr-ca', 'i-mingo')

  extract_language_tags("It's like this: I'm in fr -- French!")
  # returns:   ('It', 'in', 'fr')
  # (So don't just feed it any old thing.)

  ```
* `same_language_tag(Str:D $lang1, Str:D $lang2 --> Bool)`

  Returns `True` if `$lang1` and `$lang2` are acceptable variant tags representing the same language-form.

  ```
  same_language_tag('x-kadara', 'i-kadara')  # is True
  #   (The x/i- alternation doesn't matter)
  same_language_tag('X-KADARA', 'i-kadara')  # is True
  #   (...and neither does case)
  same_language_tag('en',       'en-US')     # is False
  #   (all-English is not the SAME as US English)
  same_language_tag('x-kadara', 'x-kadar')   # is False
  #   (these are totally unrelated tags)
  same_language_tag('no-bok',    'nb')       # is True
  #   (no-bok is a legacy tag for nb (Norwegian Bokmal))

  ```

  `same_language_tag` works by just seeing whether `encode_language_tag($lang1)` is the same as `encode_language_tag($lang2)`.

  (Yes, I know this function is named a bit oddly. Call it historic reasons.)
* `similarity_language_tag($lang1, $lang2 --> Int)`

  Returns an integer representing the degree of similarity between tags `$lang1` and `$lang2` (the order of which does not matter), where similarity is the number of common elements on the left, without regard to case and to x/i- alternation.

  ```
  similarity_language_tag('fr', 'fr-ca')           # is 1
  #   (one element in common)
  similarity_language_tag('fr-ca', 'fr-FR')        # is 1
  #   (one element in common)

  similarity_language_tag('fr-CA-joual',
                          'fr-CA-PEI')             # is 2
  similarity_language_tag('fr-CA-joual', 'fr-CA')  # is 2
  #   (two elements in common)

  similarity_language_tag('x-kadara', 'i-kadara')  # is 1
  #   (x/i- doesn't matter)

  similarity_language_tag('en',       'x-kadar')   # is 0
  similarity_language_tag('x-kadara', 'x-kadar')   # is 0
  #   (unrelated tags -- no similarity)

  similarity_language_tag('i-cree-syllabic',
                          'i-cherokee-syllabic')   # is 0
  #   (no B<leftmost> elements in common!)

  ```
* `is_dialect_of(Str:D $lang1, Str:D $lang2 -->Bool)`

  Returns `True` if language tag `$lang1` represents a subform of language tag `$lang2`.

  **Get the order right! It doesn't work the other way around!**

  ```
  is_dialect_of('en-US', 'en')            # is True
  # (American English IS a dialect of all-English)

  is_dialect_of('fr-CA-joual', 'fr-CA')   # is True
  is_dialect_of('fr-CA-joual', 'fr')      # is True
  # (Joual is a dialect of (a dialect of) French)

  is_dialect_of('en', 'en-US')            # is False
  # (all-English is a NOT dialect of American English)

  is_dialect_of('fr', 'en-CA')            # is False

  is_dialect_of('en',    'en'   )         # is True
  is_dialect_of('en-US', 'en-US')         # is True
  # (these are degenerate cases)

  is_dialect_of('i-mingo-tom', 'x-Mingo') # is True
  #  (the x/i thing doesn't matter, nor does case)

  is_dialect_of('nn', 'no')               # is True
  # (because 'nn' (New Norse) is aliased to 'no-nyn',
  #  as a special legacy case, and 'no-nyn' is a
  #  subform of 'no' (Norwegian))

  ```
* `super_languages(Str:D $lang1 --> Seq)`

  Returns a sequence of language tags that are superordinate tags to `$lang1` -- it gets this by removing subtags from the end of `$lang1` until nothing (or just "i" or "x") is left.

  ```
  super_languages("fr-CA-joual")  # is  ("fr-CA", "fr")

  super_languages("en-AU")  # is  ("en")

  super_languages("en")  # is  empty-list, ()

  super_languages("i-cherokee")  # is  empty-list, ()
  # ...not ("i"), which would be illegal as well as pointless.

  ```

  If `$lang1` is not a valid language tag, returns empty-list.

  A notable and rather unavoidable problem with this method: "x-mingo-tom" has an "x" because the whole tag isn't an IANA-registered tag -- but super\_languages('x-mingo-tom') is ('x-mingo') -- which isn't really right, since 'i-mingo' is registered. But this module has no way of knowing that. (But note that same\_language\_tag('x-mingo', 'i-mingo') is `True`.)

  More importantly, you assume *at your peril* that superordinates of `$lang1` are mutually intelligible with `$lang1`. Consider this carefully.
* `locale2language_tag(Str:D $locale_identifier --> Str)`

  This takes a locale name (like "en", "en\_US", or "en\_US.ISO8859-1") and maps it to a language tag. If it's not mappable (as with, notably, "C" and "POSIX"), this returns empty-list in a list context, or undef in a scalar context.

  ```
  locale2language_tag("en") is "en"

  locale2language_tag("en_US") is "en-US"

  locale2language_tag("en_US.ISO8859-1") is "en-US"

  locale2language_tag("C") is undef or ()

  locale2language_tag("POSIX") is undef or ()

  locale2language_tag("POSIX") is undef or ()

  ```

  I'm not totally sure that locale names map satisfactorily to language tags. Think REAL hard about how you use this. YOU HAVE BEEN WARNED.

  The output is untainted. If you don't know what tainting is, don't worry about it.
* `encode_language_tag(Str:D $lang1 -> Str)`

  This function, if given a language tag, returns an encoding of it such that:

  * tags representing different languages never get the same encoding.
  * tags representing the same language always get the same encoding.
  * an encoding of a formally valid language tag always is a string value that is defined, has length, and is true if considered as a boolean.

  Note that the encoding itself is **not** a formally valid language tag. Note also that you cannot, currently, go from an encoding back to a language tag that it's an encoding of.

  Note also that you **must** consider the encoded value as atomic; i.e., you should not consider it as anything but an opaque, unanalysable string value. (The internals of the encoding method may change in future versions, as the language tagging standard changes over time.)

  `encode_language_tag` returns `Str` if given anything other than a formally valid language tag.

  The reason `encode_language_tag` exists is because different language tags may represent the same language; this is normally treatable with `same_language_tag`, but consider this situation:

  You have a data file that expresses greetings in different languages. Its format is "[language tag]=[how to say 'Hello']", like:

  ```
  en-US=Hiho
  fr=Bonjour
  i-mingo=Hau'

  ```

  And suppose you write a program that reads that file and then runs as a daemon, answering client requests that specify a language tag and then expect the string that says how to greet in that language. So an interaction looks like:

  ```
  greeting-client asks:    fr
  greeting-server answers: Bonjour

  ```

  So far so good. But suppose the way you're implementing this is: **This is Perl 5 Code**

  ```
  my %greetings;
  die unless open(IN, "<", "in.dat");
  while(<IN>) {
    chomp;
    next unless /^([^=]+)=(.+)/s;
    my($lang, $expr) = ($1, $2);
    $greetings{$lang} = $expr;
  }
  close(IN);

  ```

  at which point %greetings has the contents:

  ```
  "en-US"   => "Hiho"
  "fr"      => "Bonjour"
  "i-mingo" => "Hau'"

  ```

  And suppose then that you answer client requests for language $wanted by just looking up $greetings{$wanted}.

  If the client asks for "fr", that will look up successfully in %greetings, to the value "Bonjour". And if the client asks for "i-mingo", that will look up successfully in %greetings, to the value "Hau'".

  But if the client asks for "i-Mingo" or "x-mingo", or "Fr", then the lookup in %greetings fails. That's the Wrong Thing.

  You could instead do lookups on $wanted with: **This is Perl 5 Code**

  ```
  use I18N::LangTags qw(same_language_tag);
  my $response = '';
  foreach my $l2 (keys %greetings) {
    if(same_language_tag($wanted, $l2)) {
      $response = $greetings{$l2};
      last;
    }
  }

  ```

  But that's rather inefficient. A better way to do it is to start your program with: **This is Perl 5 Code**

  ```
  use I18N::LangTags qw(encode_language_tag);
  my %greetings;
  die unless open(IN, "<", "in.dat");
  while(<IN>) {
    chomp;
    next unless /^([^=]+)=(.+)/s;
    my($lang, $expr) = ($1, $2);
    $greetings{
                encode_language_tag($lang)
              } = $expr;
  }
  close(IN);

  ```

  and then just answer client requests for language $wanted by just looking up **This is Perl 5 Code**

  ```
  $greetings{encode_language_tag($wanted)}

  ```

  And that does the Right Thing.
* `alternate_language_tags(Str:D $lang1 --> List)`

  This function, if given a language tag, returns all language tags that are alternate forms of this language tag. (I.e., tags which refer to the same language.) This is meant to handle legacy tags caused by the minor changes in language tag standards over the years; and the x-/i- alternation is also dealt with.

  Note that this function does *not* try to equate new (and never-used, and unusable) ISO639-2 three-letter tags to old (and still in use) ISO639-1 two-letter equivalents -- like "ara" -> "ar" -- because "ara" has *never* been in use as an Internet language tag, and RFC 3066 stipulates that it never should be, since a shorter tag ("ar") exists.

  Examples:

  ```
  alternate_language_tags('no-bok')       # is ('nb')
  alternate_language_tags('nb')           # is ('no-bok')
  alternate_language_tags('he')           # is ('iw')
  alternate_language_tags('iw')           # is ('he')
  alternate_language_tags('i-hakka')      # is ('zh-hakka', 'x-hakka')
  alternate_language_tags('zh-hakka')     # is ('i-hakka', 'x-hakka')
  alternate_language_tags('en')           # is ()
  alternate_language_tags('x-mingo-tom')  # is ('i-mingo-tom')
  alternate_language_tags('x-klikitat')   # is ('i-klikitat')
  alternate_language_tags('i-klikitat')   # is ('x-klikitat')

  ```

  This function returns empty-list if given anything other than a formally valid language tag.
* `panic_languages(@accept_languages -> Seq)`

  This function takes a list of 0 or more language tags that constitute a given user's Accept-Language list, and returns a list of tags for *other* (non-super) languages that are probably acceptable to the user, to be used *if all else fails*.

  For example, if a user accepts only 'ca' (Catalan) and 'es' (Spanish), and the documents/interfaces you have available are just in German, Italian, and Chinese, then the user will most likely want the Italian one (and not the Chinese or German one!), instead of getting nothing. So `panic_languages('ca', 'es')` returns a list containing 'it' (Italian).

  English ('en') is *always* in the return list, but whether it's at the very end or not depends on the input languages. This function works by consulting an internal table that stipulates what common languages are "close" to each other.

  A useful construct you might consider using is:

  ```
  @fallbacks = super_languages(@accept_languages);
  @fallbacks.append:  panic_languages(
    |@accept_languages, |@fallbacks,
  );

  ```
* `implicate_supers(@languages --> Seq)`

  This takes a list of strings (which are presumed to be language-tags; strings that aren't, are ignored); and after each one, this function inserts super-ordinate forms that don't already appear in the list. The original list, plus these insertions, is returned.

  In other words, it takes this:

  ```
  pt-br de-DE en-US fr pt-br-janeiro

  ```

  and returns this:

  ```
  pt-br pt de-DE de en-US en fr pt-br-janeiro

  ```

  This function is most useful in the idiom. **But detect() is not jet implemented**.

  ```
  implicate_supers( I18N::LangTags::Detect::detect() );

  ```
* `implicate_supers_strictly(@languages --> Seq)`

  This works like `implicate_supers` except that the implicated forms are added to the end of the return list.

  In other words, implicate\_supers\_strictly takes a list of strings (which are presumed to be language-tags; strings that aren't, are ignored) and after the whole given list, it inserts the super-ordinate forms of all given tags, minus any tags that already appear in the input list.

  In other words, it takes this:

  ```
  pt-br de-DE en-US fr pt-br-janeiro

  ```

  and returns this:

  ```
  pt-br de-DE en-US fr pt-br-janeiro pt de en

  ```

  The reason this function has "\_strictly" in its name is that when you're processing an Accept-Language list according to the RFCs, if you interpret the RFCs quite strictly, then you would use implicate\_supers\_strictly, but for normal use (i.e., common-sense use, as far as I'm concerned) you'd use implicate\_supers.

# SEE ALSO

* <https://metacpan.org/pod/I18N::LangTags>
* I18N::LangTags::List
* RFC 3066, `http://www.ietf.org/rfc/rfc3066.txt`, "Tags for the Identification of Languages". (Obsoletes RFC 1766)
* RFC 2277, `http://www.ietf.org/rfc/rfc2277.txt`, "IETF Policy on Character Sets and Languages".
* RFC 2231, `http://www.ietf.org/rfc/rfc2231.txt`, "MIME Parameter Value and Encoded Word Extensions: Character Sets, Languages, and Continuations".
* RFC 2482, `http://www.ietf.org/rfc/rfc2482.txt`, "Language Tagging in Unicode Plain Text".
* Locale::Codes, in `http://www.perl.com/CPAN/modules/by-module/Locale/`
* ISO 639-2, "Codes for the representation of names of languages", including two-letter and three-letter codes, `http://www.loc.gov/standards/iso639-2/php/code_list.php`
* The IANA list of registered languages (hopefully up-to-date), `http://www.iana.org/assignments/language-tags`

# AUTHOR

Martin Barth [martin@senfdax.de](mailto:martin@senfdax.de)

# COPYRIGHT AND LICENSE

Copyright 2018 Martin Barth

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


## dist_cpan-MELEZHIK-Sparky.md
# SYNOPSIS

Sparky is a flexible and minimalist continuous integration server written in Raku.

![Nice web UI](https://raw.githubusercontent.com/melezhik/sparky/master/images/sparky-web-ui5.png)

The essential features of Sparky:

* Defining builds times in crontab style
* Triggering builds using external APIs and custom logic
* Build scenarios defined as [Sparrow6](https://github.com/melezhik/Sparrow6) scripts
* [Nice set](https://github.com/melezhik/Sparrow6/blob/master/documentation/dsl.md) of predefined tasks is available
* Everything is kept in SCM repository - easy to port, maintain and track changes
* Builds gets run in one of 3 flavors - 1) on localhost 2) on remote machines via **ssh** 3) on **docker** instances
* Nice web UI to read build reports

Interested? Let's go ahead! (:

# Build status

[![Build Status](https://travis-ci.org/melezhik/sparky.svg?branch=master)](https://travis-ci.org/melezhik/sparky)

# Sparky workflow in 4 lines:

```
$ sparkyd # run Sparky daemon to build your projects
$ raku bin/sparky-web.raku # run Sparky web UI to see build statuses and reports
$ nano ~/.sparky/projects/my-project/sparrowfile  # write a build scenario
$ firefox 127.0.0.1:3000 # see what's happening

```

# Installation

```
$ sudo apt-get install sqlite3
$ git clone https://github.com/melezhik/sparky.git
$ cd sparky && zef install .

```

# Setup

First you should run database initialization script to populate database schema:

```
$ raku db-init.raku

```

# Running daemon

Then you need to run (\*) the sparky daemon

```
$ sparkyd

```

* Sparky daemon traverses sub directories found at the project root directory.
* For every directory found initiate build process invoking sparky worker ( `sparky-runner.raku` ).
* Sparky root directory default location is `~/.sparky/projects`.
* Once all the sub directories gets passed, sparky daemon sleeps for $timeout seconds.
* A `timeout` option allows to balance a load on your system.
* You can change a timeout by applying `--timeout` parameter when running sparky daemon:

```
$ sparkyd --timeout=600 # sleep 10 minutes

```

* You can also set a timeout by using `SPARKY_TIMEOUT` environment variable:

```
$ SPARKY_TIMEOUT=30 sparkyd ...

```

Running sparky in demonized mode.

At the moment sparky can't demonize itself, as temporary workaround use linux `nohup` command:

```
$ nohup sparkyd &

```

Or you can use Sparrowdo installer, which install service as systemd unit:

```
$ nano utils/install-sparky-web-systemd.raku # change working directory and user
$ sparrowdo --sparrowfile=utils/install-sparkyd-systemd.raku --no_sudo --localhost

```

\* `sparkyd` should be in your PATH, if not, fix it before going further.

You should have installed with `zef install .` listed above.

It could live for instance in `$HOME/.raku/bin` along with other scripts required (like `sparrowdo`)

# Running Web UI

And finally sparky has simple web UI to show builds statuses and reports.

To run Sparky web UI launch `sparky-web.raku` script from the `bin/` directory:

```
$ raku bin/sparky-web.raku

```

This is [Bailador](https://github.com/Bailador/Bailador) application, so you can set any Bailador related options here.

For example:

```
$ BAILADOR=host:0.0.0.0,port:5000 raku bin/sparky-web.raku

```

You can use Sparrowdo installer as well, which installs service as systemd unit:

```
$ nano utils/install-sparky-web-.raku # change working directory, user and root directory
$ sparrowdo --sparrowfile=utils/install-sparky-web-systemd.raku --no_sudo --localhost

```

# Creating first sparky project

Sparky project is just a directory located at the sparky root directory:

```
$ mkdir ~/.sparky/projects/bailador-app

```

# Build scenario

Sparky is built on Sparrowdo, read [Sparrowdo](https://github.com/melezhik/sparrowdo)
*to know how to write Sparky scenarios*. Here is a short example.

Say, we want to check out a Raku project from from Git, install dependencies and then run unit tests:

```
$ nano ~/.sparky/projects/bailador-app/sparrowfile

```

And add content like this:

```
directory "project";

git-scm 'https://github.com/melezhik/rakudist-teddy-bear.git', %(
  to => "project",
);

zef "{%*ENV<PWD>}/project", %( depsonly => True );

zef 'TAP::Harness App::Prove6';

bash 'prove6 -l', %(
  debug => True,
  cwd => "{%*ENV<PWD>}/project/"
);

```

# Configure Sparky workers

By default the build scenario gets executed *on the same machine you run Sparky at*, but you can change this
to *any remote host* setting Sparrowdo related parameters in the `sparky.yaml` file:

```
$ nano ~/.sparky/projects/bailador-app/sparky.yaml

```

And define worker configuration:

```
sparrowdo:
  host: '192.168.0.1'
  ssh_private_key: /path/to/ssh_private/key.pem
  ssh_user: sparky
  no_index_update: true
  sync: /tmp/repo

```

You can read about the all [available parameters](https://github.com/melezhik/sparrowdo#sparrowdo-cli) in Sparrowdo documentation.

# Skip bootstrap

Sparrowdo bootstrap takes a while, if you don't need bootstrap ( sparrow client is already installed at a target host )
use `bootstrap: false` option:

```
sparrowdo:
  bootstrap: false

```

# Purging old builds

To remove old build set `keep_builds` parameter in `sparky.yaml`:

```
$ nano ~/.sparky/projects/bailador-app/sparky.yaml

```

Put number of past builds to keep:

```
keep_builds: 10

```

That makes Sparky remove old build and only keep last `keep_builds` builds.

# Run by cron

It's possible to setup scheduler for Sparky builds, you should define `crontab` entry in sparky yaml file.
for example to run a build every hour at 30,50 or 55 minute say this:

```
$ nano ~/.sparky/projects/bailador-app/sparky.yaml

```

With this schedule:

```
crontab: "30,50,55 * * * *"

```

Follow [Time::Crontab](https://github.com/ufobat/p6-time-crontab) documentation on crontab entries format.

# Manual run

If you want to build a project from web UI, use `allow_manual_run`:

```
$ nano ~/.sparky/projects/bailador-app/sparky.yaml

```

And activate manual run:

```
allow_manual_run: true

```

# Trigger build by SCM changes

\*\* warning \*\* - the feature is not properly tested, feel free to post issues or suggestions

To trigger Sparky builds on SCM changes, define `scm` section in `sparky.yaml` file:

```
scm:
  url: $SCM_URL
  branch: $SCM_BRANCH

```

Where:

* `url` - git URL
* `branch` - git branch, optional, default value is `master`

For example:

```
scm:
  url: https://github.com/melezhik/rakudist-teddy-bear.git
  branch: master

```

Once a build is triggered one needs to handle build environment leveraging `tags()<SCM_*>` objects:

```
directory "scm";

say "current commit is: {tags()<SCM_SHA>}";

git-scm tags()<SCM_URL>, %(
  to => "scm",
  branch => tags<SCM_BRANCH>
);

bash "ls -l {%*ENV<PWD>}/scm";

```

# Disable project

You can disable project builds by setting `disable` option to true:

```
$ nano ~/.sparky/projects/bailador-app/sparky.yaml

disabled: true

```

It's handy when you start a new project and don't want to add it into build pipeline.

# Downstream projects

You can run downstream projects by setting `downstream` field at the upstream project `sparky.yaml` file:

```
$ nano ~/.sparky/projects/main/sparky.yaml

downstream: downstream-project

```

# File triggering protocol (FTP)

Sparky FTP allows to *trigger* builds automatically by just creating files with build *parameters*
in special format:

```
$ nano $project/.triggers/foo-bar-baz.pl6

```

File should have a `*.pl6` extension and be located in project `.trigger` directory.

A content of the file should Raku code returning a Hash:

```
{
  description => "Build app",
  cwd => "/path/to/working/directory",
  sparrowdo => %(
    localhost => True,
    no_sudo   => True,
    conf      => "/path/to/file.conf"
  )
}

```

Sparky daemon parses files in `.triggers` and launch build per every file, removing file afterwards,
this process is called file triggering.

To separate different builds just create trigger files with unique names inside `$project/.trigger` directory.

FTP allows to create *supplemental* APIs to implement more complex and custom build logic, while keeping Sparky itself simple.

## Trigger attributes

Those keys could be used in trigger Hash. All they are optional.

* `cwd`
  Directory where sparrowfile is located, when a build gets run, the process will change to this directory.
* `description`
  Arbitrary text description of build
* `sparrowdo`
  Options for sparrowdo run, for example:

```
%(
  host  => "foo.bar",
  ssh_user  => "admin",
  tags => "prod,backend"
)

```

Should follow the format of sparky.yaml, `sparrowdo` section

* `key`

A unique key

# Sparky plugins

Sparky plugins are extensions points to add extra functionality to Sparky builds.

These are Raku modules get run *after* a Sparky project finishes or in other words when a build is completed.

To use Sparky plugins you should:

* Install plugins as Raku modules
* Configure plugins in project's `sparky.yaml` file

## Install Sparky plugins

You should install a module on the same server where you run Sparky at. For instance:

```
$ zef install Sparky::Plugin::Email # Sparky plugin to send email notifications

```

## Configure Sparky

In project's `sparky.yaml` file define plugins section, it should be list of Plugins and its configurations.

For instance:

```
$ cat sparky.yaml

```

That contains:

```
plugins:
  - Sparky::Plugin::Email:
    parameters:
      subject: "I finished"
      to: "happy@user.email"
      text: "here will be log"
  - Sparky::Plugin::Hello:
    parameters:
      name: Sparrow

```

## Creating Sparky plugins

Technically speaking Sparky plugins should be just Raku modules.

For instance, for mentioned module Sparky::Plugin::Email we might have this header lines:

```
use v6;

unit module Sparky::Plugin::Hello;

```

That is it.

The module should have `run` routine which is invoked when Sparky processes a plugin:

```
our sub run ( %config, %parameters ) {

}

```

As we can see the `run` routine consumes its parameters as Raku Hash, these parameters are defined at mentioned `sparky.yaml` file,
at plugin `parameters:` section, so this is how you might handle them:

```
sub run ( %config, %parameters ) {

  say "Hello " ~ %parameters<name>;

}

```

You can use `%config` Hash to access Sparky guts:

* `%config<project>` - the project name
* `%config<build-id>` - the build number of current project build
* `%cofig<build-state>` - the state of the current build

For example:

```
sub run ( %config, %parameters ) {

  say "build id is: " ~ %parameters<build-id>;

}

```

Alternatively you may pass *some* predefined parameters plugins:

* %PROJECT% - equivalent of `%config<project>`
* %BUILD-STATE% - equivalent of `%config<build-state>`
* %BUILD-ID% - equivalent of `%config<build-id>`

For example:

```
$ cat sparky.yaml

```

That contains:

```
plugins:
  - Sparky::Plugin::Hello:
    parameters:
      name: Sparrow from project %PROJECT%

```

## Limit plugin run scope

You can defined *when* to run plugin, here are 3 run scopes:

* `anytime` - run plugin irrespective of a build state. This is default value
* `success` - run plugin only if build has succeeded
* `fail` - run plugin only if build has failed

Scopes are defined at `run_scope:` parameter:

```
- Sparky::Plugin::Hello:
  run_scope: fail
  parameters:
    name: Sparrow

```

## An example of Sparky plugins

An example Sparky plugins are:

* [Sparky::Plugin::Hello](https://github.com/melezhik/sparky-plugin-hello)
* [Sparky::Plugin::Notify::Email](https://github.com/melezhik/sparky-plugin-notify-email)

# Command line client

You can build the certain project using sparky command client called `sparky-runner.raku`:

```
$ sparky-runner.raku --dir=/home/user/.sparky/projects/bailador-app

```

Or just:

```
$ cd ~/.sparky/projects/bailador-app && sparky-runner.raku

```

# Sparky runtime parameters

All this parameters could be overridden by command line ( `--root`, `--work-root` )

## Root directory

This is sparky root directory, or directory where Sparky looks for the projects to get built:

```
~/.sparky/projects/

```

## Work directory

This is working directory where sparky might place some stuff, useless at the moment:

```
~/.sparky/work

```

# Environment variables

## SPARKY\_SKIP\_CRON

You can disable cron check to run project forcefully, by setting `SPARKY_SKIP_CRON` environment variable:

```
$ export SPARKY_SKIP_CRON=1 && sparkyd

```

## SPARKY\_ROOT

Sets the sparky root directory

## SPARKY\_HTTP\_ROOT

Set Sparky web application http root. Useful when proxy application through Nginx.

## SPARKY\_TIMEOUT

Sets timeout for sparky workers, see [Running daemon](#running-daemon) section.

# Running under other databases engines (MySQL, PostgreSQL)

By default Sparky uses sqlite as database engine, which makes it easy to use when developing.
However sqlite has limitation on transactions locking whole database when doing inserts/updates (Database Is Locked errors).

if you prefer other databases here is guideline.

## Create sparky configuration file

You should defined database engine and connection parameters, say we want to use MySQL:

```
$ nano ~/sparky.yaml

```

With content:

```
database:
  engine: mysql
  host: $dbhost
  port: $dbport
  name: $dbname
  user: $dbuser
  pass: $dbpassword

```

For example:

```
database:
  engine: mysql
  host: "127.0.0.1"
  port: 3306
  name: sparky
  user: sparky
  pass: "123"

```

## Installs dependencies

Depending on platform it should be client needed for your database API, for example for Debian we have to:

```
$ sudo yum install mysql-client

```

## Creating database user, password and schema

DB init script will generate database schema, provided that user defined and sparky configuration file has access to
the database:

```
$ raku db-init.raku

```

That is it, now sparky runs under MySQL!

# Change UI theme

Sparky uses [Bulma](https://bulma.io/) as a CSS framework, you can easily change the theme
through sparky configuration file:

```
$ nano ~/sparky.yaml

```

And choose your theme:

```
ui:
  theme: cosmo

```

The list of available themes is on <https://jenil.github.io/bulmaswatch/>

# Trigger jobs from HTTP API

```
POST /build/project/$project

```

# Examples

You can see examples of sparky scenarios in `examples/` folder.

# See also

[Bailador](https://github.com/Bailador/Bailador) - A light-weight route-based web application framework for Perl 6.
[Sparky-docker](https://github.com/melezhik/sparky-docker) - Run Sparky as Docker container.

# Author

Alexey Melezhik


## dist_github-jaffa4-Rakudo-Perl6-Parsing.md
# Rakudo::Perl6::Parsing

It is a wrapper around nqp Perl6 parsing methods.
Known problem: if it is compiled into pir. (Panda does that), use Perl6::Parsing fails. It seems to be a Rakudo bug.
Workaround: delete Parsing.pir.

Usage:

```
use Rakudo::Perl6::Parsing;

my $p=  Rakudo::Perl6::Parsing.new(); # create a new object

$p.parse("my \$p=3;");  # let us parse this text <br>
say $p.parser.dump; # dumps parse tree

$p.printree(); #prints the parse tree using a different format

my @tokens = $p.tokenise(); # extract tokens , requires $p.parse...
Instead of tokens, it would be more accurate to say parsed texts. It may be useful for all kind of Perl 6 analysis.

@tokens is a array of [hash (keys are tokentypes or parsing events, values are charpos where the token may ends), startpos in text, endpos in text ].
There are overlapping tokens but no overlaps are returned. Look at the values of the hash to determine overlaps. <br>
E.g. values in the previous line is not equal to endpos in text.

say $p.text.substr(@tokens[0][1],@tokens[0][2]-@tokens[0][1]); # prints first token

Tokens are derived from parse tree. It means the token boundaries may not be where you expect them to be. <br>
For example, two consecutive comments may be returned as one token. Token boundaries are derived from what the parser considered to be important: code mainly.

say @tokens.perl; # look at the structure

say $p.dumptokens(); # shows better view

```


## dist_zef-dwarring-FDF.md
[[Raku PDF Project]](https://pdf-raku.github.io)
/ [[FDF Module]](https://pdf-raku.github.io/FDF-raku)

# FDF-raku

A Raku module for the creation and manipulation of FDF (Form Data Format)
files, including PDF export and import.

## Classes/Roles in this Distribution

* [FDF](https://pdf-raku.github.io/FDF-raku/FDF) - FDF file
* [FDF::Annot](https://pdf-raku.github.io/FDF-raku/FDF/Annot) - FDF Annotations
* [FDF::Catalog](https://pdf-raku.github.io/FDF-raku/FDF/Catalog) - FDF Catalog
* [FDF::Dict](https://pdf-raku.github.io/FDF-raku/FDF/Dict) - FDF Main Dictionary
* [FDF::Field](https://pdf-raku.github.io/FDF-raku/FDF/Field) - FDF Fields
* [FDF::Field::AdditionalActions](https://pdf-raku.github.io/FDF-raku/FDF/Field/AdditionalActions) - FDF Field Additional Actions
* [FDF::IconFit](https://pdf-raku.github.io/FDF-raku/FDF/IconFit) - FDF IconFits
* [FDF::JavaScript](https://pdf-raku.github.io/FDF-raku/FDF/JavaScript) - FDF JavaScripts
* [FDF::NamedPageRef](https://pdf-raku.github.io/FDF-raku/FDF/NamedPageRef) - FDF Named Page References
* [FDF::Page](https://pdf-raku.github.io/FDF-raku/FDF/Page) - FDF Pages to be added
* [FDF::Template](https://pdf-raku.github.io/FDF-raku/FDF/Template) - FDF Page Templates

## Synopsis

### Export fields from a PDF to an FDF

```
use PDF::Class;
use FDF;
my PDF::Class $from .= open: "MyDoc.pdf";
my FDF $fdf .= new;

# fill the email field, overriding PDF value
my %fill = :email<david.warring@gmail.com>;

# Combined import and filling
$fdf.import: :$from, :%fill;
# -OR- import then fill
$fdf.import: :$from;
$fdf.import: :%fill;

note "saving fields :-"
for $fdf.field-hash.sort {
    note " - {.key}: {.value.perl}";
}

$fdf.save-as: "MyDoc.fdf";

```

### List field values in an FDF file

```
use FDF;
use FDF::Field;
my FDF $fdf .= open: "MyDoc.fdf";

my FDF::Fields @fields = $fdf.fields;
for @fields {
    say .key ~ ': ' ~ .value.raku;
}

```

### Export field data from an FDF to a PDF

```
use PDF::Class;
use FDF;
my PDF::Class $to .= open: "MyDoc.pdf";
my FDF $fdf .= open: "MyDoc.fdf";

# populate form data from the PDF
$fdf.export: :$to;

# save updated fields
$to.update;

```

## Description

FDF (Form Data Format) is a format for storing form data and formatting or
annotations seperately from PDF files.

## Bugs and Limitations

Not yet handled:

* Form signing and signature manipulation
* Import/export of annotations and pages
* Custom encodings (`/Encoding` entry in the FDF dictionary)


## dist_cpan-MOZNION-HTML-Escape.md
[![Build Status](https://travis-ci.org/moznion/p6-HTML-Escape.svg?branch=master)](https://travis-ci.org/moznion/p6-HTML-Escape)

# NAME

HTML::Escape - Utility of HTML escaping

# SYNOPSIS

```
use HTML::Escape;

escape-html("<^o^>"); # => '<^o^>'

```

# DESCRIPTION

HTML::Escape provides a function which escapes HTML's special characters. It performs a similar function to PHP's htmlspecialchars.

This module is perl6 port of [HTML::Escape of perl5](https://metacpan.org/pod/HTML::Escape).

# Functions

## `escape-html(Str $raw-str) returns Str`

Escapes HTML's special characters in given string.

# TODO

* Support unescaping function?

# SEE ALSO

[HTML::Escape of perl5](https://metacpan.org/pod/HTML::Escape)

# COPYRIGHT AND LICENSE

```
Copyright 2017- moznion <moznion@gmail.com>

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

```

And original perl5's HTML::Escape is

```
This software is copyright (c) 2012 by Tokuhiro Matsuno E<lt>tokuhirom AAJKLFJEF@ GMAIL COME<gt>.

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

```


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

# NAME

Raku port of Perl's times() built-in

# SYNOPSIS

```
use P5times; # exports times()

($user,$system,$cuser,$csystem) = times;

$user = times(Scalar);

```

# DESCRIPTION

This module tries to mimic the behaviour of Perl's `times` built-in as closely as possible in the Raku Programming Language.

# ORIGINAL PERL DOCUMENTATION

```
times   Returns a four-element list giving the user and system times in
        seconds for this process and any exited children of this process.

            ($user,$system,$cuser,$csystem) = times;

        In scalar context, "times" returns $user.

        Children's times are only included for terminated children.

        Portability issues: "times" in perlport.

```

# PORTING CAVEATS

## Microseconds vs Seconds

Due to a misunderstanding, it was found that the the `times` function returns **microseconds** versus seconds (as the original Perl version does). This was only found after two years of this module's existence, and deemed much more useful in the Raku context.

Therefore it was decided to keep this behaviour in December 2020.

## Child process information

There is currently no way to obtain the usage information of child processes.

# AUTHOR

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

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

# COPYRIGHT AND LICENSE

Copyright 2018, 2019, 2020, 2021 Elizabeth Mattijsen

Re-imagined from Perl as part of the CPAN Butterfly Plan.

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


## timezoneclash.md
class X::DateTime::TimezoneClash

Error due to using both time zone offset and :timezone

```raku
class X::DateTime::TimezoneClash does X::Temporal is Exception { }

```

This exception is thrown when code tries to create a [`DateTime`](/type/DateTime) object specifying both a time zone offset and the named argument `:timezone`.

```raku
say DateTime.new('2015-12-24T12:23:00+0200');                   # works
say DateTime.new('2015-12-24T12:23:00', timezone => 7200);      # works
say DateTime.new('2015-12-24T12:23:00+0200', timezone => 7200); # exception

```

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

## [method message](#class_X::DateTime::TimezoneClash "go to top of document")[§](#method_message "direct link")

```raku
method message()
```

Returns 'DateTime.new(Str): :timezone argument not allowed with a timestamp offset'


## dist_github-melezhik-Sparrowdo-Rakudo.md
# Sparrowdo::Rakudo

[![Build Status](https://travis-ci.org/melezhik/perl6-sparrowdo-rakudo.svg?branch=master)](https://travis-ci.org/melezhik/perl6-sparrowdo-rakudo)

## SYNOPSIS

## Via sparrowfile

```
$ cat sparrowfile

# install default version
module_run 'Rakudo';

# install specific version
module_run 'Rakudo', %(
  version => 'https://github.com/nxadm/rakudo-pkg/releases/download/2017.02/perl6-rakudo-moarvm-ubuntu16.04_20170200-01_i386.deb'
)

```

## Via sparrowdo command line:

```
# install default version
$ sparrowdo --host=192.168.0.1 --module_run=Rakudo
# install specific version
$ sparrowdo --host=192.168.0.1 --module_run=Rakudo@version=https://github.com/nxadm/rakudo-pkg/releases/download/2017.02/perl6-rakudo-moarvm-ubuntu16.04_20170200-01_i386.deb

```

# Description

This is simple installer of Rakudo Perl6.

# Platforms supported:

```
CentOS
Ubuntu

```

## LICENSE

All files (unless noted otherwise) can be used, modified and redistributed
under the terms of the Artistic License Version 2. Examples (in the
documentation, in tests or distributed as separate files) can be considered
public domain.

ⓒ2017 'Alexey Melezhik'


## dist_github-gfldex-Operator-DynvarOr.md
# Operator::DynvarOr

[![Build Status](https://travis-ci.org/gfldex/raku-operator-dynvaror.svg?branch=master)](https://travis-ci.org/gfldex/raku-operator-dynvaror)

## SYNOPSIS

```
use Operator::DynvarOr;

sub s {
    my $*dynvar //* 42;
}

s;

```

This module supplies the infix operator `//*` that expects its LHS to be a
dynvar and its RHS a value. It scans the call stack for a dynvar of the same
name and sets the LHS to its value. If the dynvar is not declared in any
caller it will assign the RHS to the LHS. This allows optional dynvars to
contain undefined values which is otherwise difficult to achieve.

## LICENSE

All files (unless noted otherwise) can be used, modified and redistributed
under the terms of the Artistic License Version 2. Examples (in the
documentation, in tests or distributed as separate files) can be considered
public domain.

ⓒ2020 Wenzel P. P. Peppmeyer