class Range

Interval of ordered values

class Range is Cool does Iterable does Positional {}

Ranges serve two main purposes: to generate lists of consecutive numbers or strings, and to act as a matcher to check if a number or string is within a certain range.

Ranges are constructed using one of the four possible range operators, which consist of two dots, and optionally a caret which indicates that the endpoint marked with it is excluded from the range.

1 .. 5;  # 1 <= $x <= 5 
1^.. 5;  # 1 <  $x <= 5 
1 ..^5;  # 1 <= $x <  5 
1^..^5;  # 1 <  $x <  5

The caret is also a prefix operator for constructing numeric ranges starting from zero:

my $x = 10;
say ^$x;     # same as 0 ..^ $x.Numeric

Iterating a range (or calling the list method) uses the same semantics as the ++ prefix and postfix operators, i.e., it calls the succ method on the start point, and then the generated elements.

Ranges always go from small to larger elements; if the start point is bigger than the end point, the range is considered empty.

for 1..5 { .say };           # OUTPUT: «1␤2␤3␤4␤5␤» 
say ('a' ^..^ 'f').list;     # OUTPUT: «(b c d e)␤» 
say 5 ~~ ^5;                 # OUTPUT: «False␤» 
say 4.5 ~~ 0..^5;            # OUTPUT: «True␤» 
say (1.1..5).list;           # OUTPUT: «(1.1 2.1 3.1 4.1)␤»

Use the ... sequence operator to produce lists of elements that go from larger to smaller values, or to use offsets other than increment-by-1 and other complex cases.

Use or * (Whatever) to indicate an end point to be open-ended.

for 1..* { .say };       # start from 1, continue until stopped 
for 1..∞ { .say };       # the same 

Beware that a WhateverCode end point, instead of a plain Whatever, will go through the range operator and create another WhateverCode which returns a Range:

# A Whatever produces the 1..Inf range 
say (1..*).^name;        # OUTPUT: «Range␤» 
say (1..*);              # OUTPUT: «1..Inf␤» 
# Upper end point is now a WhateverCode 
say (1..*+20).^name;     # OUTPUT: «{ ... }␤» 
say (1..*+20).WHAT;      # OUTPUT: «(WhateverCode)␤» 
say (1..*+20).(22);      # OUTPUT: «1..42␤» 

Ranges implement Positional interface, so its elements can be accessed using an index. In a case when the index given is bigger than the Range object's size, Nil object will be returned. The access works for lazy Range objects as well.

say (1..5)[1];  # OUTPUT: «2␤» 
say (1..5)[10]; # OUTPUT: «Nil␤» 
say (1..*)[10]; # OUTPUT: «11␤» 

Ranges in subscripts

A Range can be used in a subscript to get a range of values. Please note that assigning a Range to a scalar container turns the Range into an item. Use binding, @-sigiled containers or a slip to get what you mean.

my @numbers =  <4 8 15 16 23 42>;
my $range := 0..2;
.say for @numbers[$range]; # OUTPUT: «4␤8␤15␤» 
my @range = 0..2;
.say for @numbers[@range]; # OUTPUT: «4␤8␤15␤»

Shifting and scaling intervals

It is possible to shift or scale the interval of a range:

say (1..10+ 1;       # OUTPUT: «2..11␤» 
say (1..10- 1;       # OUTPUT: «0..9␤» 
say (1..10* 2;       # OUTPUT: «2..20␤» 
say (1..10/ 2;       # OUTPUT: «0.5..5.0␤»

Matching against Ranges

You can use smartmatch to match against Ranges.

say 3 ~~ 1..12;          # OUTPUT: «True␤» 
say 2..3 ~~ 1..12;       # OUTPUT: «True␤»

In Rakudo only, you can use the in-range method for matching against a range, which in fact is equivalent to smartmatch except it will throw an exception when out of range, instead of returning False:

say ('א'..'ת').in-range('ע');  # OUTPUT: «True␤»

However, if it is not included in the range:

say ('א'..'ת').in-range('p'"Letter 'p'");
# OUTPUT: «(exit code 1) Letter 'p' out of range. Is: "p", should be in "א".."ת"␤ 

The second parameter to in-range is the optional message that will be printed with the exception. It will print Value by default.

Methods

method ACCEPTS

Defined as

multi method ACCEPTS(Range:D: Mu \topic)
multi method ACCEPTS(Range:D: Range \topic)
multi method ACCEPTS(Range:D: Cool:D \got)
multi method ACCEPTS(Range:D: Complex:D \got)

Indicates if the Range contains (overlaps with) another Range. As an example:

my $p = Range.new35  );
my $r = Range.new110 );
 
say $p.ACCEPTS$r );    # OUTPUT: «False␤» 
say $r.ACCEPTS$p );    # OUTPUT: «True␤» 
say $r ~~ $p;            # OUTPUT: «False␤»  (same as $p.ACCEPTS( $r ) 
say $p ~~ $r;            # OUTPUT: «True␤»   (same as $r.ACCEPTS( $p )

Of course, an infinite Range always contains another Range, therefore:

say 1..10 ~~ -∞..∞;    # OUTPUT: «True␤» 
say 1..10 ~~ -∞^..^∞;  # OUTPUT: «True␤»

Similarly, a Range with open boundaries often includes other ranges:

say 1..2 ~~ *..10;  # OUTPUT: «True␤» 
say 2..5 ~~ 1..*;   # OUTPUT: «True␤»

It is also possible to use non-numeric ranges, for instance string based ones:

say 'a'..'j' ~~ 'b'..'c';  # OUTPUT: «False␤» 
say 'b'..'c' ~~ 'a'..'j';  # OUTPUT: «True␤» 
say 'raku' ~~ -∞^..^∞;     # OUTPUT: «True␤» 
say 'raku' ~~ -∞..∞;       # OUTPUT: «True␤» 
say 'raku' ~~ 1..*;        # OUTPUT: «True␤»

When smartmatching a Range of integers with a Cool (string) the ACCEPTS methods exploits the before and after operators in order to check that the Cool value is overlapping the range:

say 1.10 ~~ '5';   # OUTPUT: «False␤» 
say '5' before 1;  # OUTPUT: «False␤» 
say '5' after 10;  # OUTPUT: «True␤» 
say '5' ~~ *..10;  # OUTPUT: «False␤»

In the above example, since the '5' string is after the 10 integer value, the Range does not overlap with the specified value.

When matching with a Mu instance (i.e., a generic instance), the cmp operator is used.

method min

method min(Range:D:)

Returns the start point of the range.

say (1..5).min;                                   # OUTPUT: «1␤» 
say (1^..^5).min;                                 # OUTPUT: «1␤»

method excludes-min

method excludes-min(Range:D: --> Bool:D)

Returns True if the start point is excluded from the range, and False otherwise.

say (1..5).excludes-min;                          # OUTPUT: «False␤» 
say (1^..^5).excludes-min;                        # OUTPUT: «True␤»

method max

method max(Range:D:)

Returns the end point of the range.

say (1..5).max;                                   # OUTPUT: «5␤» 
say (1^..^5).max;                                 # OUTPUT: «5␤»

method excludes-max

method excludes-max(Range:D: --> Bool:D)

Returns True if the end point is excluded from the range, and False otherwise.

say (1..5).excludes-max;                          # OUTPUT: «False␤» 
say (1^..^5).excludes-max;                        # OUTPUT: «True␤»

method bounds

method bounds()

Returns a list consisting of the start and end point.

say (1..5).bounds;                                # OUTPUT: «(1 5)␤» 
say (1^..^5).bounds;                              # OUTPUT: «(1 5)␤»

method infinite

method infinite(Range:D: --> Bool:D)

Returns True if either end point was declared with or *.

say (1..5).infinite;                              # OUTPUT: «False␤» 
say (1..*).infinite;                              # OUTPUT: «True␤»

method is-int

method is-int(Range:D: --> Bool:D)

Returns True if both end points are Int values.

say ('a'..'d').is-int;                            # OUTPUT: «False␤» 
say (1..^5).is-int;                               # OUTPUT: «True␤» 
say (1.1..5.5).is-int;                            # OUTPUT: «False␤»

method int-bounds

proto method int-bounds(|)
multi method int-bounds()
multi method int-bounds($from is rw$to is rw --> Bool:D)

If the Range is an integer range (as indicated by is-int), then this method returns a list with the first and last value it will iterate over (taking into account excludes-min and excludes-max). Returns a Failure if it is not an integer range.

say (2..5).int-bounds;                            # OUTPUT: «(2 5)␤» 
say (2..^5).int-bounds;                           # OUTPUT: «(2 4)␤»

If called with (writable) arguments, these will take the values of the higher and lower bound and returns whether integer bounds could be determined from the Range:

if (3..5).int-boundsmy $minmy $max{
    say "$min$max" ; # OUTPUT: «3, 5␤» 
}
else {
    say "Could not determine integer bounds";
}

method minmax

Defined as:

multi method minmax(Range:D: --> List:D)

If the Range is an integer range (as indicated by is-int), then this method returns a list with the first and last value it will iterate over (taking into account excludes-min and excludes-max). If the range is not an integer range, the method will return a two element list containing the start and end point of the range unless either of excludes-min or excludes-max are True in which case a Failure is returned.

my $r1 = (1..5); my $r2 = (1^..5);
say $r1.is-int''$r2.is-int;                 # OUTPUT: «True, True␤» 
say $r1.excludes-min''$r2.excludes-min;     # OUTPUT: «False, True␤» 
say $r1.minmax''$r2.minmax;                 # OUTPUT: «(1 5), (2 5)␤» 
 
my $r3 = (1.1..5.2); my $r4 = (1.1..^5.2);
say $r3.is-int''$r4.is-int;                 # OUTPUT: «False, False␤» 
say $r3.excludes-max''$r4.excludes-max;     # OUTPUT: «False, True␤» 
say $r3.minmax;                                   # OUTPUT: «(1.1 5.2)␤» 
say $r4.minmax;
CATCH { default { put .^name''.Str } };
# OUTPUT: «X::AdHoc: Cannot return minmax on Range with excluded ends␤»

method elems

method elems(Range:D: --> Numeric:D)

Returns the number of elements in the range, e.g. when being iterated over, or when used as a List. Returns 0 if the start point is larger than the end point, including when the start point was specified as . Fails when the Range is lazy, including when the end point was specified as or either end point was specified as *.

say (1..5).elems;                                 # OUTPUT: «5␤» 
say (1^..^5).elems;                               # OUTPUT: «3␤»

method list

multi method list(Range:D:)

Generates the list of elements that the range represents.

say (1..5).list;                                  # OUTPUT: «(1 2 3 4 5)␤» 
say (1^..^5).list;                                # OUTPUT: «(2 3 4)␤»

method flat

method flat(Range:D:)

Generates a Seq containing the elements that the range represents.

method pick

multi method pick(Range:D:         --> Any:D)
multi method pick(Range:D: $number --> Seq:D)

Performs the same function as Range.list.pick, but attempts to optimize by not actually generating the list if it is not necessary.

method roll

multi method roll(Range:D:         --> Any:D)
multi method roll(Range:D: $number --> Seq:D)

Performs the same function as Range.list.roll, but attempts to optimize by not actually generating the list if it is not necessary.

method sum

multi method sum(--> Numeric:D)

Returns the sum of all elements in the Range. Throws X::Str::Numeric if an element can not be coerced into Numeric.

(1..10).sum                                       # 55

method reverse

method reverse(Range:D: --> Seq:D)

Returns a Seq where all elements that the Range represents have been reversed. Note that reversing an infinite Range won't produce any meaningful results.

say (1^..5).reverse;                            # OUTPUT: «(5 4 3 2)␤» 
say ('a'..'d').reverse;                         # OUTPUT: «(d c b a)␤» 
say (1..∞).reverse;                             # OUTPUT: «(Inf Inf Inf ...)␤» 

method Capture

Defined as:

method Capture(Range:D: --> Capture:D)

Returns a Capture with values of .min .max, .excludes-min, .excludes-max, .infinite, and .is-int as named arguments.

method rand

Defined as:

method rand(Range:D --> Num:D)

Returns a pseudo-random value belonging to the range.

say (1^..5).rand;                              # OUTPUT: «1.02405550417031␤» 
say (0.1..0.3).rand;                           # OUTPUT: «0.2130353370062␤»

method EXISTS-POS

Defined as

multi method EXISTS-POS(Range:D: int \pos)
multi method EXISTS-POS(Range:D: Int \pos)

Returns True if pos is greater than or equal to zero and lower than self.elems. Returns False otherwise.

say (6..10).EXISTS-POS(2); # OUTPUT: «True␤» 
say (6..10).EXISTS-POS(7); # OUTPUT: «False␤»

method AT-POS

Defined as

multi method AT-POS(Range:D: int \pos)
multi method AT-POS(Range:D: int:D \pos)

Checks if the Int position exists and in that case returns the element in that position.

say (1..4).AT-POS(2# OUTPUT: «3␤»

method raku

Defined as

multi method raku(Range:D:)

Returns an implementation-specific string that produces an equivalent object when given to EVAL.

say (1..2).raku # OUTPUT: «1..2␤» 

method fmt

Defined as

method fmt(|c)

Returns a string where min and max in the Range have been formatted according to |c.

For more information about parameters, see List.fmt.

say (1..2).fmt("Element: %d"","# OUTPUT: «Element: 1,Element: 2␤»

method WHICH

Defined as

multi method WHICH (Range:D:)

This returns a string that identifies the object. The string is composed by the type of the instance (Range) and the min and max attributes:

say (1..2).WHICH # OUTPUT: «Range|1..2␤»

sub infix:<+>

multi sub infix:<+>(Range:D \rReal:D \v)
multi sub infix:<+>(Real:D \vRange:D \r)

Takes an Real and adds that number to both boundaries of the Range object. Be careful with the use of parenthesis.

say (1..2+ 2# OUTPUT: «3..4␤» 
say 1..2 + 2;   # OUTPUT: «1..4␤»

sub infix:<->

multi sub infix:<->(Range:D \rReal:D \v)

Takes an Real and subtract that number to both boundaries of the Range object. Be careful with the use of parenthesis.

say (1..2- 1# OUTPUT: «0..1␤» 
say 1..2 - 1;   # OUTPUT: «1..1␤»

sub infix:<*>

multi sub infix:<*>(Range:D \rReal:D \v)
multi sub infix:<*>(Real:D \vRange:D \r)

Takes an Real and multiply both boundaries of the Range object by that number.

say (1..2* 2# OUTPUT: «2..4␤»

sub infix:</>

multi sub infix:</>(Range:D \rReal:D \v)

Takes an Real and divide both boundaries of the Range object by that number.

say (2..4/ 2# OUTPUT: «1..2␤»

sub infix:<cmp>

multi sub infix:<cmp>(Range:D \aRange:D \b --> Order:D)
multi sub infix:<cmp>(Num(Real) \aRange:D \b --> Order:D)
multi sub infix:<cmp>(Range:D \aNum(Real) \b --> Order:D)
multi sub infix:<cmp>(Positional \aRange:D \b --> Order:D)
multi sub infix:<cmp>(Range:D \aPositional \b --> Order:D)

Compares two Range objects. A Real operand will be considered as both the starting point and the ending point of a Range to be compared with the other operand. A Positional operand will be compared with the list returned by the .list method applied to the other operand. See List infix:<cmp>

say (1..2cmp (1..2); # OUTPUT: «Same␤» 
say (1..2cmp (1..3); # OUTPUT: «Less␤» 
say (1..4cmp (1..3); # OUTPUT: «More␤» 
say (1..2cmp 3;      # OUTPUT: «Less␤» 
say (1..2cmp [1,2];  # OUTPUT: «Same␤»

Type Graph

Type relations for Range
perl6-type-graph Range Range Cool Cool Range->Cool Positional Positional Range->Positional Iterable Iterable Range->Iterable Mu Mu Any Any Any->Mu Cool->Any

Expand above chart

Routines supplied by role Positional

Range does role Positional, which provides the following routines:

(Positional) method of

method of()

Returns the type constraint for elements of the positional container, that is, the T in the definition above, which, as it can be seen, defaults to Mu. It is returned as a type object.

my @þ;
say @þ.of.^name;   # OUTPUT: «Mu␤ 
my Str @þð;
say @þð.of.raku;   # OUTPUT: «Str␤» 
say (my int @).of# OUTPUT: «(int)␤» 

(Positional) method elems

method elems()

Should return the number of available elements in the instantiated object.

(Positional) method AT-POS

method AT-POS(\position)

Should return the value / container at the given position.

(Positional) method EXISTS-POS

method EXISTS-POS(\position)

Should return a Bool indicating whether the given position actually has a value.

(Positional) method STORE

method STORE(\values:$INITIALIZE)

This method should only be supplied if you want to support the:

my @a is Foo = 1,2,3;

syntax for binding your implementation of the Positional role.

Should accept the values to (re-)initialize the object with. The optional named parameter will contain a True value when the method is called on the object for the first time. Should return the invocant.

Routines supplied by role Iterable

Range does role Iterable, which provides the following routines:

(Iterable) method iterator

Defined as:

method iterator(--> Iterator:D)

Method stub that ensures all classes doing the Iterable role have a method iterator.

It is supposed to return an Iterator.

say (1..10).iterator;

(Iterable) method flat

Defined as:

method flat(Iterable:D: --> Iterable)

Returns another Iterable that flattens out all iterables that the first one returns.

For example

say (<a b>'c').elems;         # OUTPUT: «2␤» 
say (<a b>'c').flat.elems;    # OUTPUT: «3␤»

because <a b> is a List and thus iterable, so (<a b>, 'c').flat returns ('a', 'b', 'c'), which has three elems.

Note that the flattening is recursive, so ((("a", "b"), "c"), "d").flat returns ("a", "b", "c", "d"), but it does not flatten itemized sublists:

say ($('a''b'), 'c').raku;    # OUTPUT: «($("a", "b"), "c")␤»

You can use the hyper method call to call the .List method on all the inner itemized sublists and so de-containerize them, so that flat can flatten them:

say ($('a''b'), 'c')>>.List.flat.elems;    # OUTPUT: «3␤»

(Iterable) method lazy

Defined as:

method lazy(--> Iterable)

Returns a lazy iterable wrapping the invocant.

say (1 ... 1000).is-lazy;      # OUTPUT: «False␤» 
say (1 ... 1000).lazy.is-lazy# OUTPUT: «True␤»

(Iterable) method hyper

Defined as:

method hyper(Int(Cool:$batch = 64Int(Cool:$degree = 4)

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

The order of elements is preserved.

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

Use hyper in situations where it is OK to do the processing of items in parallel, and the output order should be kept relative to the input order. See race for situations where items are processed in parallel and the output order does not matter.

Options degree and batch

The degree option (short for "degree of parallelism") configures how many parallel workers should be started. To start 4 workers (e.g. to use at most 4 cores), pass :4degree to the hyper or race method. Note that in some cases, choosing a degree higher than the available CPU cores can make sense, for example I/O bound work or latency-heavy tasks like web crawling. For CPU-bound work, however, it makes no sense to pick a number higher than the CPU core count.

The batch size option configures the number of items sent to a given parallel worker at once. It allows for making a throughput/latency trade-off. If, for example, an operation is long-running per item, and you need the first results as soon as possible, set it to 1. That means every parallel worker gets 1 item to process at a time, and reports the result as soon as possible. In consequence, the overhead for inter-thread communication is maximized. In the other extreme, if you have 1000 items to process and 10 workers, and you give every worker a batch of 100 items, you will incur minimal overhead for dispatching the items, but you will only get the first results when 100 items are processed by the fastest worker (or, for hyper, when the worker getting the first batch returns.) Also, if not all items take the same amount of time to process, you might run into the situation where some workers are already done and sit around without being able to help with the remaining work. In situations where not all items take the same time to process, and you don't want too much inter-thread communication overhead, picking a number somewhere in the middle makes sense. Your aim might be to keep all workers about evenly busy to make best use of the resources available.

You can also check out this blog post on the semantics of hyper and race

(Iterable) method race

Defined as:

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

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

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

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

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

Blog post on the semantics of hyper and race

See hyper for an explanation of :$batch and :$degree.

Routines supplied by class Cool

Range inherits from class Cool, which provides the following routines:

(Cool) routine abs

Defined as:

sub abs(Numeric() $x)
method abs()

Coerces the invocant (or in the sub form, the argument) to Numeric and returns the absolute value (that is, a non-negative number).

say (-2).abs;       # OUTPUT: «2␤» 
say abs "6+8i";     # OUTPUT: «10␤»

(Cool) method conj

Defined as:

method conj()

Coerces the invocant to Numeric and returns the complex conjugate (that is, the number with the sign of the imaginary part negated).

say (1+2i).conj;        # OUTPUT: «1-2i␤»

(Cool) method EVAL

Defined as:

method EVAL(*%_)

It calls the subroutine form with the invocant as the first argument, $code, passing along named args, if any.

(Cool) routine sqrt

Defined as:

sub sqrt(Numeric(Cool$x)
method sqrt()

Coerces the invocant to Numeric (or in the sub form, the argument) and returns the square root, that is, a non-negative number that, when multiplied with itself, produces the original number.

say 4.sqrt;             # OUTPUT: «2␤» 
say sqrt(2);            # OUTPUT: «1.4142135623731␤»

(Cool) method sign

Defined as:

method sign()

Coerces the invocant to Numeric and returns its sign, that is, 0 if the number is 0, 1 for positive and -1 for negative values.

say 6.sign;             # OUTPUT: «1␤» 
say (-6).sign;          # OUTPUT: «-1␤» 
say "0".sign;           # OUTPUT: «0␤»

(Cool) method rand

Defined as:

method rand()

Coerces the invocant to Num and returns a pseudo-random value between zero and the number.

say 1e5.rand;           # OUTPUT: «33128.495184283␤»

(Cool) routine sin

Defined as:

sub sin(Numeric(Cool))
method sin()

Coerces the invocant (or in the sub form, the argument) to Numeric, interprets it as radians, returns its sine.

say sin(0);             # OUTPUT: «0␤» 
say sin(pi/4);          # OUTPUT: «0.707106781186547␤» 
say sin(pi/2);          # OUTPUT: «1␤»

Note that Raku is no computer algebra system, so sin(pi) typically does not produce an exact 0, but rather a very small floating-point number.

(Cool) routine asin

Defined as:

sub asin(Numeric(Cool))
method asin()

Coerces the invocant (or in the sub form, the argument) to Numeric, and returns its arc-sine in radians.

say 0.1.asin;               # OUTPUT: «0.10016742116156␤» 
say asin(0.1);              # OUTPUT: «0.10016742116156␤»

(Cool) routine cos

Defined as:

sub cos(Numeric(Cool))
method cos()

Coerces the invocant (or in sub form, the argument) to Numeric, interprets it as radians, returns its cosine.

say 0.cos;                  # OUTPUT: «1␤» 
say pi.cos;                 # OUTPUT: «-1␤» 
say cos(pi/2);              # OUTPUT: «6.12323399573677e-17␤»

(Cool) routine acos

Defined as:

sub acos(Numeric(Cool))
method acos()

Coerces the invocant (or in sub form, the argument) to Numeric, and returns its arc-cosine in radians.

say 1.acos;                 # OUTPUT: «0␤» 
say acos(-1);               # OUTPUT: «3.14159265358979␤»

(Cool) routine tan

Defined as:

sub tan(Numeric(Cool))
method tan()

Coerces the invocant (or in sub form, the argument) to Numeric, interprets it as radians, returns its tangent.

say tan(3);                 # OUTPUT: «-0.142546543074278␤» 
say 3.tan;                  # OUTPUT: «-0.142546543074278␤»

(Cool) routine atan

Defined as:

sub atan(Numeric(Cool))
method atan()

Coerces the invocant (or in sub form, the argument) to Numeric, and returns its arc-tangent in radians.

say atan(3);                # OUTPUT: «1.24904577239825␤» 
say 3.atan;                 # OUTPUT: «1.24904577239825␤»

(Cool) routine atan2

Defined as:

sub atan2($y$x = 1e0)
method atan2($x = 1e0)

The sub should usually be written with two arguments for clarity as it is seen in other languages and in mathematical texts, but the single-argument form is available; its result will always match that of atan.

say atan2 31;             # OUTPUT: «1.2490457723982544␤» 
say atan2 3;                # OUTPUT: «1.2490457723982544␤» 
say atan2 ⅔, ⅓;             # OUTPUT: «1.1071487177940904␤»

The method coerces self and its single argument to Numeric, using them to compute the two-argument arc-tangent in radians.

say 3.atan2;                # OUTPUT: «1.24904577239825␤» 
say ⅔.atan2(⅓);             # OUTPUT: «1.1071487177940904␤»

The $x argument in either the method or the sub defaults to 1 so, in both single-argument cases, the function will return the angle θ in radians between the x-axis and a vector that goes from the origin to the point (3, 1).

(Cool) routine sec

Defined as:

sub sec(Numeric(Cool))
method sec()

Coerces the invocant (or in sub form, its argument) to Numeric, interprets it as radians, returns its secant, that is, the reciprocal of its cosine.

say 45.sec;                 # OUTPUT: «1.90359440740442␤» 
say sec(45);                # OUTPUT: «1.90359440740442␤»

(Cool) routine asec

Defined as:

sub asec(Numeric(Cool))
method asec()

Coerces the invocant (or in sub form, its argument) to Numeric, and returns its arc-secant in radians.

say 1.asec;                 # OUTPUT: «0␤» 
say sqrt(2).asec;           # OUTPUT: «0.785398163397448␤»

(Cool) routine cosec

Defined as:

sub cosec(Numeric(Cool))
method cosec()

Coerces the invocant (or in sub form, its argument) to Numeric, interprets it as radians, returns its cosecant, that is, the reciprocal of its sine.

say 0.45.cosec;             # OUTPUT: «2.29903273150897␤» 
say cosec(0.45);            # OUTPUT: «2.29903273150897␤»

(Cool) routine acosec

Defined as:

sub acosec(Numeric(Cool))
method acosec()

Coerces the invocant (or in sub form, its argument) to Numeric, and returns its arc-cosecant in radians.

say 45.acosec;              # OUTPUT: «0.0222240516182672␤» 
say acosec(45)              # OUTPUT: «0.0222240516182672␤»

(Cool) routine cotan

Defined as:

sub cotan(Numeric(Cool))
method cotan()

Coerces the invocant (or in sub form, its argument) to Numeric, interprets it as radians, returns its cotangent, that is, the reciprocal of its tangent.

say 45.cotan;               # OUTPUT: «0.617369623783555␤» 
say cotan(45);              # OUTPUT: «0.617369623783555␤»

(Cool) routine acotan

Defined as:

sub acotan(Numeric(Cool))
method acotan()

Coerces the invocant (or in sub form, its argument) to Numeric, and returns its arc-cotangent in radians.

say 45.acotan;              # OUTPUT: «0.0222185653267191␤» 
say acotan(45)              # OUTPUT: «0.0222185653267191␤»

(Cool) routine sinh

Defined as:

sub sinh(Numeric(Cool))
method sinh()

Coerces the invocant (or in method form, its argument) to Numeric, and returns its Sine hyperbolicus.

say 1.sinh;                 # OUTPUT: «1.1752011936438␤» 
say sinh(1);                # OUTPUT: «1.1752011936438␤»

(Cool) routine asinh

Defined as:

sub asinh(Numeric(Cool))
method asinh()

Coerces the invocant (or in sub form, its argument) to Numeric, and returns its Inverse Sine hyperbolicus.

say 1.asinh;                # OUTPUT: «0.881373587019543␤» 
say asinh(1);               # OUTPUT: «0.881373587019543␤»

(Cool) routine cosh

Defined as:

sub cosh(Numeric(Cool))
method cosh()

Coerces the invocant (or in sub form, its argument) to Numeric, and returns its Cosine hyperbolicus.

say cosh(0.5);              # OUTPUT: «1.12762596520638␤»

(Cool) routine acosh

Defined as:

sub acosh(Numeric(Cool))
method acosh()

Coerces the invocant (or in sub form, its argument) to Numeric, and returns its Inverse Cosine hyperbolicus.

say acosh(45);              # OUTPUT: «4.4996861906715␤»

(Cool) routine tanh

Defined as:

sub tanh(Numeric(Cool))
method tanh()

Coerces the invocant (or in sub form, its argument) to Numeric, interprets it as radians and returns its Tangent hyperbolicus.

say tanh(0.5);              # OUTPUT: «0.46211715726001␤» 
say tanh(atanh(0.5));       # OUTPUT: «0.5␤»

(Cool) routine atanh

Defined as:

sub atanh(Numeric(Cool))
method atanh()

Coerces the invocant (or in sub form, its argument) to Numeric, and returns its Inverse tangent hyperbolicus.

say atanh(0.5);             # OUTPUT: «0.549306144334055␤»

(Cool) routine sech

Defined as:

sub sech(Numeric(Cool))
method sech()

Coerces the invocant (or in sub form, its argument) to Numeric, and returns its Secant hyperbolicus.

say 0.sech;                 # OUTPUT: «1␤»

(Cool) routine asech

Defined as:

sub asech(Numeric(Cool))
method asech()

Coerces the invocant (or in sub form, its argument) to Numeric, and returns its Inverse hyperbolic secant.

say 0.8.asech;              # OUTPUT: «0.693147180559945␤»

(Cool) routine cosech

Defined as:

sub cosech(Numeric(Cool))
method cosech()

Coerces the invocant (or in sub form, its argument) to Numeric, and returns its Hyperbolic cosecant.

say cosech(pi/2);           # OUTPUT: «0.434537208094696␤»

(Cool) routine acosech

Defined as:

sub acosech(Numeric(Cool))
method acosech()

Coerces the invocant (or in sub form, its argument) to Numeric, and returns its Inverse hyperbolic cosecant.

say acosech(4.5);           # OUTPUT: «0.220432720979802␤»

(Cool) routine cotanh

Defined as:

sub cotanh(Numeric(Cool))
method cotanh()

Coerces the invocant (or in sub form, its argument) to Numeric, and returns its Hyperbolic cotangent.

say cotanh(pi);             # OUTPUT: «1.00374187319732␤»

(Cool) routine acotanh

Defined as:

sub acotanh(Numeric(Cool))
method acotanh()

Coerces the invocant (or in sub form, its argument) to Numeric, and returns its Inverse hyperbolic cotangent.

say acotanh(2.5);           # OUTPUT: «0.423648930193602␤»

(Cool) routine cis

Defined as:

sub cis(Numeric(Cool))
method cis()

Coerces the invocant (or in sub form, its argument) to Numeric, and returns cos(argument) + i*sin(argument).

say cis(pi/4);              # OUTPUT: «0.707106781186548+0.707106781186547i␤»

(Cool) routine log

Defined as:

multi sub log(Numeric(Cool$numberNumeric(Cool$base?)
multi method log(Cool:D: Cool:D $base?)

Coerces the arguments (including the invocant in the method form) to Numeric, and returns its Logarithm to base $base, or to base e (Euler's Number) if no base was supplied (Natural logarithm). Returns NaN if $base is negative. Throws an exception if $base is 1.

say (e*e).log;              # OUTPUT: «2␤»

(Cool) routine log10

Defined as:

multi method log10()
multi sub log10(Numeric $x)
multi sub log10(Cool    $x)

Coerces the invocant (or in the sub form, the argument) to Numeric (or uses it directly if it's already in that form), and returns its Logarithm in base 10, that is, a number that approximately produces the original number when 10 is raised to its power. Returns NaN for negative arguments and -Inf for 0.

say log10(1001);            # OUTPUT: «3.00043407747932␤»

(Cool) routine log2

Defined as:

multi method log2()
multi sub log2(Numeric $x)
multi sub log2(Cool    $x)

Coerces the invocant to Numeric, and returns its Logarithm in base 2, that is, a number that approximately (due to computer precision limitations) produces the original number when 2 is raised to its power. Returns NaN for negative arguments and -Inf for 0.

say log2(5);            # OUTPUT: «2.321928094887362␤» 
say "4".log2;           # OUTPUT: «2␤» 
say 4.log2;             # OUTPUT: «2␤»

(Cool) routine exp

Defined as:

multi sub exp(Cool:D $powCool:D $base?)
multi method exp(Cool:D: Cool:D $base?)

Coerces the arguments (including the invocant in the method from) to Numeric, and returns $base raised to the power of the first number. If no $base is supplied, e (Euler's Number) is used.

say 0.exp;      # OUTPUT: «1␤» 
say 1.exp;      # OUTPUT: «2.71828182845905␤» 
say 10.exp;     # OUTPUT: «22026.4657948067␤»

(Cool) method unpolar

Defined as:

method unpolar(Numeric(Cool))

Coerces the arguments (including the invocant in the method form) to Numeric, and returns a complex number from the given polar coordinates. The invocant (or the first argument in sub form) is the magnitude while the argument (i.e. the second argument in sub form) is the angle. The angle is assumed to be in radians.

say sqrt(2).unpolar(pi/4);      # OUTPUT: «1+1i␤»

(Cool) routine round

Defined as:

multi sub round(Numeric(Cool), $scale = 1)
multi method round(Cool:D: $scale = 1)

Coerces the invocant (or in sub form, its argument) to Numeric, and rounds it to the unit of $scale. If $scale is 1, rounds to the nearest integer; an arbitrary scale will result in the closest multiple of that number.

say 1.7.round;          # OUTPUT: «2␤» 
say 1.07.round(0.1);    # OUTPUT: «1.1␤» 
say 21.round(10);       # OUTPUT: «20␤» 
say round(100023.01)  # OUTPUT: «989.43»

Always rounds up if the number is at mid-point:

say (−.5 ).round;       # OUTPUT: «0␤» 
say ( .5 ).round;       # OUTPUT: «1␤» 
say (−.55).round(.1);   # OUTPUT: «-0.5␤» 
say ( .55).round(.1);   # OUTPUT: «0.6␤»

Pay attention to types when using this method, as ending up with the wrong type may affect the precision you seek to achieve. For Real types, the type of the result is the type of the argument (Complex argument gets coerced to Real, ending up a Num). If rounding a Complex, the result is Complex as well, regardless of the type of the argument.

9930972392403501.round(1)      .raku.say# OUTPUT: «9930972392403501␤» 
9930972392403501.round(1e0)    .raku.say# OUTPUT: «9.9309723924035e+15␤» 
9930972392403501.round(1e0).Int.raku.say# OUTPUT: «9930972392403500␤»

(Cool) routine floor

Defined as:

multi sub floor(Numeric(Cool))
multi method floor

Coerces the invocant (or in sub form, its argument) to Numeric, and rounds it downwards to the nearest integer.

say "1.99".floor;       # OUTPUT: «1␤» 
say "-1.9".floor;       # OUTPUT: «-2␤» 
say 0.floor;            # OUTPUT: «0␤»

(Cool) method fmt

Defined as:

method fmt($format = '%s')

Uses $format to return a formatted representation of the invocant; equivalent to calling sprintf with $format as format and the invocant as the second argument. The $format will be coerced to Stringy and defaults to '%s'.

For more information about formats strings, see sprintf.

say 11.fmt('This Int equals %03d');         # OUTPUT: «This Int equals 011␤» 
say '16'.fmt('Hexadecimal %x');             # OUTPUT: «Hexadecimal 10␤»

(Cool) routine ceiling

Defined as:

multi sub ceiling(Numeric(Cool))
multi method ceiling

Coerces the invocant (or in sub form, its argument) to Numeric, and rounds it upwards to the nearest integer.

say "1".ceiling;        # OUTPUT: «1␤» 
say "-0.9".ceiling;     # OUTPUT: «0␤» 
say "42.1".ceiling;     # OUTPUT: «43␤»

(Cool) routine truncate

Defined as:

multi sub truncate(Numeric(Cool))
multi method truncate()

Coerces the invocant (or in sub form, its argument) to Numeric, and rounds it towards zero.

say 1.2.truncate;       # OUTPUT: «1␤» 
say truncate -1.2;      # OUTPUT: «-1␤»

(Cool) routine ord

Defined as:

sub ord(Str(Cool))
method ord()

Coerces the invocant (or in sub form, its argument) to Str, and returns the Unicode code point number of the first code point.

say 'a'.ord;            # OUTPUT: «97␤»

The inverse operation is chr.

Mnemonic: returns an ordinal number

(Cool) method path

Defined as:

method path()

DEPRECATED. It's been deprecated as of the 6.d version. Will be removed in the next ones.

Stringifies the invocant and converts it to IO::Path object. Use the .IO method instead.

(Cool) routine chr

Defined as:

sub chr(Int(Cool))
method chr()

Coerces the invocant (or in sub form, its argument) to Int, interprets it as a Unicode code points, and returns a string made of that code point.

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

The inverse operation is ord.

Mnemonic: turns an integer into a character.

(Cool) routine chars

Defined as:

multi sub chars(Cool $x)
multi sub chars(Str:D $x)
multi sub chars(str $x --> int)
method chars(--> Int:D)

Coerces the invocant (or in sub form, its argument) to Str, and returns the number of characters in the string. Please note that on the JVM, you currently get codepoints instead of graphemes.

say 'møp'.chars;    # OUTPUT: «3␤» 
say 'ã̷̠̬̊'.chars;     # OUTPUT: «1␤» 
say '👨‍👩‍👧‍👦🏿'.chars;    # OUTPUT: «1␤»

If the string is native, the number of chars will be also returned as a native int.

Graphemes are user visible characters. That is, this is what the user thinks of as a “character”.

Graphemes can contain more than one codepoint. Typically the number of graphemes and codepoints differs when Prepend or Extend characters are involved (also known as Combining characters), but there are many other cases when this may happen. Another example is \c[ZWJ] (Zero-width joiner).

You can check Grapheme_Cluster_Break property of a character in order to see how it is going to behave:

say ã̷̠̬̊.uniprops(Grapheme_Cluster_Break); # OUTPUT: «(Other Extend Extend Extend Extend)␤» 
say 👨‍👩‍👧‍👦🏿.uniprops(Grapheme_Cluster_Break); # OUTPUT: «(E_Base_GAZ ZWJ E_Base_GAZ ZWJ E_Base_GAZ ZWJ E_Base_GAZ E_Modifier)␤»

You can read more about graphemes in the Unicode Standard, which Raku tightly follows, using a method called NFG, normal form graphemes for efficiently representing them.

(Cool) routine codes

Defined as:

sub codes(Str(Cool))
method codes()

Coerces the invocant (or in sub form, its argument) to Str, and returns the number of Unicode code points.

say 'møp'.codes;    # OUTPUT: «3␤»

The same result will be obtained with

say +'møp'.ords;    # OUTPUT: «3␤»

ords first obtains the actual codepoints, so there might be a difference in speed.

(Cool) routine flip

Defined as:

sub flip(Cool $s --> Str:D)
method flip()

Coerces the invocant (or in sub form, its argument) to Str, and returns a reversed version.

say 421.flip;       # OUTPUT: «124␤»

(Cool) routine trim

Defined as:

sub trim(Str(Cool))
method trim()

Coerces the invocant (or in sub form, its argument) to Str, and returns the string with both leading and trailing whitespace stripped.

my $stripped = '  abc '.trim;
say "<$stripped>";          # OUTPUT: «<abc>␤»

(Cool) routine trim-leading

Defined as:

sub trim-leading(Str(Cool))
method trim-leading()

Coerces the invocant (or in sub form, its argument) to Str, and returns the string with leading whitespace stripped.

my $stripped = '  abc '.trim-leading;
say "<$stripped>";          # OUTPUT: «<abc >␤»

(Cool) routine trim-trailing

Defined as:

sub trim-trailing(Str(Cool))
method trim-trailing()

Coerces the invocant (or in sub form, its argument) to Str, and returns the string with trailing whitespace stripped.

my $stripped = '  abc '.trim-trailing;
say "<$stripped>";          # OUTPUT: «<  abc>␤»

(Cool) routine lc

Defined as:

sub lc(Str(Cool))
method lc()

Coerces the invocant (or in sub form, its argument) to Str, and returns it case-folded to lower case.

say "ABC".lc;       # OUTPUT: «abc␤»

(Cool) routine uc

Defined as:

sub uc(Str(Cool))
method uc()

Coerces the invocant (or in sub form, its argument) to Str, and returns it case-folded to upper case (capital letters).

say "Abc".uc;       # OUTPUT: «ABC␤»

(Cool) routine fc

Defined as:

sub fc(Str(Cool))
method fc()

Coerces the invocant (or in sub form, its argument) to Str, and returns the result a Unicode "case fold" operation suitable for doing caseless string comparisons. (In general, the returned string is unlikely to be useful for any purpose other than comparison.)

say "groß".fc;       # OUTPUT: «gross␤»

(Cool) routine tc

Defined as:

sub tc(Str(Cool))
method tc()

Coerces the invocant (or in sub form, its argument) to Str, and returns it with the first letter case-folded to title case (or where not available, upper case).

say "abC".tc;       # OUTPUT: «AbC␤»

(Cool) routine tclc

Defined as:

sub tclc(Str(Cool))
method tclc()

Coerces the invocant (or in sub form, its argument) to Str, and returns it with the first letter case-folded to title case (or where not available, upper case), and the rest of the string case-folded to lower case.

say 'abC'.tclc;     # OUTPUT: «Abc␤»

(Cool) routine wordcase

Defined as:

sub wordcase(Str(Cool$input:&filter = &tclcMu :$where = True)
method wordcase(:&filter = &tclcMu :$where = True)

Coerces the invocant (or in sub form, the first argument) to Str, and filters each word that smartmatches against $where through the &filter. With the default filter (first character to upper case, rest to lower) and matcher (which accepts everything), this title-cases each word:

say "raku programming".wordcase;        # OUTPUT: «Raku Programming␤»

With a matcher:

say "have fun working on raku".wordcase(:where({ .chars > 3 }));
                                        # Have fun Working on Raku

With a customer filter too:

say "have fun working on raku".wordcase(:filter(&uc), :where({ .chars > 3 }));
                                        # HAVE fun WORKING on RAKU

(Cool) routine samecase

Defined as:

sub samecase(Cool $stringCool $pattern)
method samecase(Cool:D: Cool $pattern)

Coerces the invocant (or in sub form, the first argument) to Str, and calls Str.samecase on it.

say "raKu".samecase("A_a_"); # OUTPUT: «Raku␤» 
say "rAKU".samecase("Ab");   # OUTPUT: «Raku␤»

(Cool) routine uniprop

Defined as:

multi sub uniprop(Str:D|c)
multi sub uniprop(Int:D $code)
multi sub uniprop(Int:D $codeStringy:D $propname)
multi method uniprop(|c)

Returns the unicode property of the first character. If no property is specified returns the General Category. Returns a Bool for Boolean properties. A uniprops routine can be used to get the property for every character in a string.

say 'a'.uniprop;               # OUTPUT: «Ll␤» 
say '1'.uniprop;               # OUTPUT: «Nd␤» 
say 'a'.uniprop('Alphabetic'); # OUTPUT: «True␤» 
say '1'.uniprop('Alphabetic'); # OUTPUT: «False␤»

(Cool) sub uniprops

Defined as:

sub uniprops(Str:D $strStringy:D $propname = "General_Category")

Interprets the invocant as a Str, and returns the unicode property for each character as a Seq. If no property is specified returns the General Category. Returns a Bool for Boolean properties. Similar to uniprop, but for each character in the passed string.

(Cool) routine uniname

Defined as:

sub uniname(Str(Cool--> Str)
method uniname(--> Str)

Interprets the invocant or first argument as a Str, and returns the Unicode codepoint name of the first codepoint of the first character. See uninames for a routine that works with multiple codepoints, and uniparse for the opposite direction.

# Camelia in Unicode 
say »ö«.uniname;
# OUTPUT: «RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK␤» 
say "Ḍ̇".uniname# Note, doesn't show "COMBINING DOT ABOVE" 
# OUTPUT: «LATIN CAPITAL LETTER D WITH DOT BELOW␤» 
 
# Find the char with the longest Unicode name. 
say (0..0x1FFFF).sort(*.uniname.chars)[*-1].chr.uniname;
# OUTPUT: «BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE RIGHT AND MIDDLE LEFT TO LOWER CENTRE␤»

(Cool) routine uninames

Defined as:

sub uninames(Str:D)
method uninames()

Returns of a Seq of Unicode names for the all the codepoints in the Str provided.

say »ö«.uninames.raku;
# OUTPUT: «("RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK", "LATIN SMALL LETTER O WITH DIAERESIS", "LEFT-POINTING DOUBLE ANGLE QUOTATION MARK").Seq␤»

Note this example, which gets a Seq where each element is a Seq of all the codepoints in that character.

say "Ḍ̇'oh".comb>>.uninames.raku;
# OUTPUT: «(("LATIN CAPITAL LETTER D WITH DOT BELOW", "COMBINING DOT ABOVE").Seq, ("APOSTROPHE",).Seq, ("LATIN SMALL LETTER O",).Seq, ("LATIN SMALL LETTER H",).Seq)␤»

See uniparse for the opposite direction.

(Cool) routine unimatch

Defined as:

multi sub unimatch(Str:D $str|c)
multi sub unimatch(Int:D $codeStringy:D $pvalnameStringy:D $propname = $pvalname)

Checks if the given integer codepoint or the first letter of the given string has a unicode property equal to the value you give. If you supply the Unicode property to be checked it will only return True if that property matches the given value.

say unimatch 'A''Latin';           # OUTPUT: «True␤» 
say unimatch 'A''Latin''Script'# OUTPUT: «True␤» 
say unimatch 'A''Ll';              # OUTPUT: «False␤»

The last property corresponds to "lowercase letter", which explains why it returns false.

(Cool) routine chop

Defined as:

sub chop(Str(Cool))
method chop()

Coerces the invocant (or in sub form, its argument) to Str, and returns it with the last character removed.

say 'raku'.chop;                        # OUTPUT: «rak␤»

(Cool) routine chomp

Defined as:

sub chomp(Str(Cool))
method chomp()

Coerces the invocant (or in sub form, its argument) to Str, and returns it with the last character removed, if it is a logical newline.

say 'ab'.chomp.chars;                   # OUTPUT: «2␤» 
say "a\n".chomp.chars;                  # OUTPUT: «1␤»

(Cool) routine substr

Defined as:

sub substr(Str(Cool$str|c)
method substr(|c)

Coerces the invocant (or in the sub form, the first argument) to Str, and calls Str.substr with the arguments.

(Cool) routine substr-rw

Defined as:

multi method substr-rw(|) is rw
multi sub substr-rw(|) is rw

Coerces the invocant (or in the sub form, the first argument) to Str, and calls Str.substr-rw with the arguments.

(Cool) routine ords

Defined as:

sub ords(Str(Cool$str)
method ords()

Coerces the invocant (or in the sub form, the first argument) to Str, and returns a list of Unicode codepoints for each character.

say "Camelia".ords;              # OUTPUT: «67 97 109 101 108 105 97␤» 
say ords 10;                     # OUTPUT: «49 48␤»

This is the list-returning version of ord. The inverse operation in chrs. If you are only interested in the number of codepoints, codes is a possibly faster option.

(Cool) routine chrs

Defined as:

sub chrs(*@codepoints --> Str:D)
method chrs()

Coerces the invocant (or in the sub form, the argument list) to a list of integers, and returns the string created by interpreting each integer as a Unicode codepoint, and joining the characters.

say <67 97 109 101 108 105 97>.chrs;   # OUTPUT: «Camelia␤»

This is the list-input version of chr. The inverse operation is ords.

(Cool) routine split

Defined as:

multi sub    split(  Str:D $delimiterStr(Cool$input$limit = Inf:$k:$v:$kv:$p:$skip-empty)
multi sub    split(Regex:D $delimiterStr(Cool$input$limit = Inf:$k:$v:$kv:$p:$skip-empty)
multi sub    split(@delimitersStr(Cool$input$limit = Inf:$k:$v:$kv:$p:$skip-empty)
multi method split(  Str:D $delimiter$limit = Inf:$k:$v:$kv:$p:$skip-empty)
multi method split(Regex:D $delimiter$limit = Inf:$k:$v:$kv:$p:$skip-empty)
multi method split(@delimiters$limit = Inf:$k:$v:$kv:$p:$skip-empty)

[1]

Coerces the invocant (or in the sub form, the second argument) to Str, splits it into pieces based on delimiters found in the string and returns the result as a Seq.

If $delimiter is a string, it is searched for literally and not treated as a regex. You can also provide multiple delimiters by specifying them as a list, which can mix Cool and Regex objects.

say split(';'"a;b;c").raku;               # OUTPUT: «("a", "b", "c").Seq␤» 
say split(';'"a;b;c"2).raku;            # OUTPUT: «("a", "b;c").Seq␤» 
 
say split(';'"a;b;c,d").raku;             # OUTPUT: «("a", "b", "c,d").Seq␤» 
say split(/\;/"a;b;c,d").raku;            # OUTPUT: «("a", "b", "c,d").Seq␤» 
say split(/<[;,]>/"a;b;c,d").raku;        # OUTPUT: «("a", "b", "c", "d").Seq␤» 
 
say split(['a', /b+/4], '1a2bb345').raku# OUTPUT: «("1", "2", "3", "5").Seq␤»

By default, split omits the matches, and returns a list of only those parts of the string that did not match. Specifying one of the :k, :v, :kv, :p adverbs changes that. Think of the matches as a list that is interleaved with the non-matching parts.

The :v interleaves the values of that list, which will be either Match objects, if a Regex was used as a matcher in the split, or Str objects, if a Cool was used as matcher. If multiple delimiters are specified, Match objects will be generated for all of them, unless all of the delimiters are Cool.

say 'abc'.split(/b/:v);               # OUTPUT: «(a 「b」 c)␤» 
say 'abc'.split('b':v);               # OUTPUT: «(a b c)␤»

:k interleaves the keys, that is, the indexes:

say 'abc'.split(/b/:k);               # OUTPUT: «(a 0 c)␤»

:kv adds both indexes and matches:

say 'abc'.split(/b/:kv);               # OUTPUT: «(a 0 「b」 c)␤»

and :p adds them as Pairs, using the same types for values as :v does:

say 'abc'.split(/b/:p);               # OUTPUT: «(a 0 => 「b」 c)␤» 
say 'abc'.split('b':p);               # OUTPUT: «(a 0 => b c)␤»

You can only use one of the :k, :v, :kv, :p adverbs in a single call to split.

Note that empty chunks are not removed from the result list. For that behavior, use the :skip-empty named argument:

say ("f,,b,c,d".split: /","/             ).raku;  # OUTPUT: «("f", "", "b", "c", "d").Seq␤» 
say ("f,,b,c,d".split: /","/:skip-empty).raku;  # OUTPUT: «("f", "b", "c", "d").Seq␤»

(Cool) routine lines

Defined as:

sub lines(Str(Cool))
method lines()

Coerces the invocant (and in sub form, the argument) to Str, decomposes it into lines (with the newline characters stripped), and returns the list of lines.

say lines("a\nb\n").join('|');          # OUTPUT: «a|b␤» 
say "some\nmore\nlines".lines.elems;    # OUTPUT: «3␤»

This method can be used as part of an IO::Path to process a file line-by-line, since IO::Path objects inherit from Cool, e.g.:

for 'huge-csv'.IO.lines -> $line {
    # Do something with $line 
}
 
# or if you'll be processing later 
my @lines = 'huge-csv'.IO.lines;

Without any arguments, sub lines operates on $*ARGFILES.

To modify values in place use is copy to force a writable container.

for $*IN.lines -> $_ is copy { s/(\w+)/{$0 ~ $0}/.say }

(Cool) method words

Defined as:

method words(Cool:D: |c)

Coerces the invocant (or first argument, if it is called as a subroutine) to Str, and returns a list of words that make up the string. Check Str.words for additional arguments and its meaning.

say <The quick brown fox>.words.join('|');     # OUTPUT: «The|quick|brown|fox␤» 
say <The quick brown fox>.words(2).join('|');  # OUTPUT: «The|quick␤» 

Cool is the base class for many other classes, and some of them, like Match, can be converted to a string. This is what happens in this case:

say ( "easy come, easy goes" ~~ m:g/(ea\w+)/).words(Inf);
# OUTPUT: «(easy easy)␤» 
say words"easy come, easy goes" ~~ m:g/(ea\w+)/ , ∞);
# OUTPUT: «(easy easy)␤»

The example above illustrates two of the ways words can be invoked, with the first argument turned into invocant by its signature. Of course, Inf is the default value of the second argument, so in both cases (and forms) it can be simply omitted.

Only whitespace (including no-break space) counts as word boundaries

say <Flying on a Boeing 747>.words.join('|');  # OUTPUT: «Flying|on|a|Boeing|747␤»

In this case, "Boeing 747" includes a (visible only in the source) no-break space; words still splits the (resulting) Str on it, even if the original array only had 4 elements:

say <Flying on a Boeing 747>.join('|');        # OUTPUT: «Flying|on|a|Boeing 747␤»

Please see Str.words for more examples and ways to invoke it.

(Cool) routine comb

Defined as:

multi sub comb(Regex $matcherCool $input$limit = *)
multi sub comb(Str $matcherCool $input$limit = *)
multi sub comb(Int:D $sizeCool $input$limit = *)
multi method comb(|c)

Returns a Seq of all (or if supplied, at most $limit) matches of the invocant (method form) or the second argument (sub form) against the Regex, string or defined number.

say "6 or 12".comb(/\d+/).join("");           # OUTPUT: «6, 12␤» 
say comb(/\d <[1..9]> /,(11..30)).join("--");
# OUTPUT: 
# «11--12--13--14--15--16--17--18--19--21--22--23--24--25--26--27--28--29␤»

The second statement exemplifies the first form of comb, with a Regex that excludes multiples of ten, and a Range (which is Cool) as $input. comb stringifies the Range before applying .comb on the resulting string. Check Str.comb for its effect on different kind of input strings. When the first argument is an integer, it indicates the (maximum) size of the chunks the input is going to be divided in

say comb(3,[3,33,333,3333]).join("*");  # OUTPUT: «3 3*3 3*33 *333*3␤»

In this case the input is a list, which after transformation to Str (which includes the spaces) is divided in chunks of size 3.

(Cool) method contains

Defined as:

method contains(Cool:D: |c)

Coerces the invocant to a Str, and calls Str.contains on it. Please refer to that version of the method for arguments and general syntax.

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

Since Int is a subclass of Cool, 123 is coerced to a Str and then contains is called on it.

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

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

(Cool) routine index

Defined as:

multi sub index(Cool:D $sCool:D $needle:i(:$ignorecase), :m(:$ignoremark--> Int:D)
multi sub index(Cool:D $sCool:D $needleCool:D $pos:i(:$ignorecase), :m(:$ignoremark--> Int:D)
multi method index(Cool:D: Cool:D $needle --> Int:D)
multi method index(Cool:D: Cool:D $needle:m(:$ignoremark)! --> Int:D)
multi method index(Cool:D: Cool:D $needle:i(:$ignorecase)!:m(:$ignoremark--> Int:D)
multi method index(Cool:D: Cool:D $needleCool:D $pos --> Int:D)
multi method index(Cool:D: Cool:D $needleCool:D $pos:m(:$ignoremark)!  --> Int:D)
multi method index(Cool:D: Cool:D $needleCool:D $pos:i(:$ignorecase)!:m(:$ignoremark--> Int:D)

Coerces the first two arguments (in method form, also counting the invocant) to a Str, and searches for $needle in the string $s starting from $pos. It returns the offset into the string where $needle was found, and Nil if it was not found.

See the documentation in type Str for examples.

(Cool) routine rindex

Defined as:

multi sub rindex(Cool:D $sCool:D $needle --> Int:D)
multi sub rindex(Cool:D $sCool:D $needleCool:D $pos --> Int:D)
multi method rindex(Cool:D: Cool:D $needle --> Int:D)
multi method rindex(Cool:D: Cool:D $needleCool:D $pos --> Int:D)

Coerces the first two arguments (including the invocant in method form) to Str and $pos to Int, and returns the last position of $needle in the string not after $pos. Returns Nil if $needle wasn't found.

See the documentation in type Str for examples.

(Cool) method match

Defined as:

method match(Cool:D: $target*%adverbs)

Coerces the invocant to Stringy and calls the method match on it.

(Cool) routine roots

Defined as:

multi sub roots(Numeric(Cool$xInt(Cool$n)
multi method roots(Int(Cool$n)

Coerces the first argument (and in method form, the invocant) to Numeric and the second ($n) to Int, and produces a list of $n Complex $n-roots, which means numbers that, raised to the $nth power, approximately produce the original number.

For example

my $original = 16;
my @roots = $original.roots(4);
say @roots;
 
for @roots -> $r {
    say abs($r ** 4 - $original);
}
 
# OUTPUT:«2+0i 1.22464679914735e-16+2i -2+2.44929359829471e-16i -3.67394039744206e-16-2i␤» 
# OUTPUT:«1.77635683940025e-15␤» 
# OUTPUT:«4.30267170434156e-15␤» 
# OUTPUT:«8.03651692704705e-15␤» 
# OUTPUT:«1.04441561648202e-14␤» 

(Cool) method subst

Defined as:

method subst(|)

Coerces the invocant to Stringy and calls Str.subst.

(Cool) method trans

Defined as:

method trans(|)

Coerces the invocant to Str and calls Str.trans

(Cool) method IO

Defined as:

method IO(--> IO::Path:D)

Coerces the invocant to IO::Path.

.say for '.'.IO.dir;        # gives a directory listing 

(Cool) method sprintf

Defined as:

method sprintf(*@args)

Returns a string according to a series format directives that are common in many languages; the object will be the format string, while the supplied arguments will be what's going to be formatted according to it.

"% 6s".sprintf('Þor').say# OUTPUT: «   Þor␤» 

(Cool) method printf

Defined as:

method printf(*@args)

Uses the object, as long as it is a format string, to format and print the arguments

"%.8f".printf(now - now ); # OUTPUT: «-0.00004118» 

(Cool) method Complex

Defined as:

multi method Complex()

Coerces the invocant to a Numeric and calls its .Complex method. Fails if the coercion to a Numeric cannot be done.

say 1+1i.Complex;         # OUTPUT: «1+1i␤» 
say π.Complex;            # OUTPUT: «3.141592653589793+0i␤» 
say <1.3>.Complex;        # OUTPUT: «1.3+0i␤» 
say (-4/3).Complex;       # OUTPUT: «-1.3333333333333333+0i␤» 
say "foo".Complex.^name;  # OUTPUT: «Failure␤»

(Cool) method FatRat

Defined as:

multi method FatRat()

Coerces the invocant to a Numeric and calls its .FatRat method. Fails if the coercion to a Numeric cannot be done.

say 1+0i.FatRat;          # OUTPUT: «1␤» 
say 2e1.FatRat;           # OUTPUT: «20␤» 
say 1.3.FatRat;           # OUTPUT: «1.3␤» 
say (-4/3).FatRat;        # OUTPUT: «-1.333333␤» 
say "foo".FatRat.^name;   # OUTPUT: «Failure␤»

(Cool) method Int

Defined as:

multi method Int()

Coerces the invocant to a Numeric and calls its .Int method. Fails if the coercion to a Numeric cannot be done.

say 1+0i.Int;             # OUTPUT: «1␤» 
say <2e1>.Int;            # OUTPUT: «20␤» 
say 1.3.Int;              # OUTPUT: «1␤» 
say (-4/3).Int;           # OUTPUT: «-1␤» 
say "foo".Int.^name;      # OUTPUT: «Failure␤»

(Cool) method Num

Defined as:

multi method Num()

Coerces the invocant to a Numeric and calls its .Num method. Fails if the coercion to a Numeric cannot be done.

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

(Cool) method Rat

Defined as:

multi method Rat()

Coerces the invocant to a Numeric and calls its .Rat method. Fails if the coercion to a Numeric cannot be done.

say 1+0i.Rat;                             # OUTPUT: «1␤» 
say 2e1.Rat;                              # OUTPUT: «20␤» 
say (-4/3).Rat;                           # OUTPUT: «-1.333333␤» 
say "foo".Rat.^name;                      # OUTPUT: «Failure␤» 
say (.numerator.denominatorfor π.Rat# OUTPUT: «(355 113)␤»

(Cool) method Real

Defined as:

multi method Real()

Coerces the invocant to a Numeric and calls its .Real method. Fails if the coercion to a Numeric cannot be done.

say 1+0i.Real;            # OUTPUT: «1␤» 
say 2e1.Real;             # OUTPUT: «20␤» 
say 1.3.Real;             # OUTPUT: «1.3␤» 
say (-4/3).Real;          # OUTPUT: «-1.333333␤» 
say "foo".Real.^name;     # OUTPUT: «Failure␤»

(Cool) method UInt

Defined as:

multi method UInt()

Coerces the invocant to an Int. Fails if the coercion to an Int cannot be done or if the Int the invocant had been coerced to is negative.

say 1+0i.UInt;            # OUTPUT: «1␤» 
say 2e1.UInt;             # OUTPUT: «20␤» 
say 1.3.UInt;             # OUTPUT: «1␤» 
say (-4/3).UInt.^name;    # OUTPUT: «Failure␤» 
say "foo".UInt.^name;     # OUTPUT: «Failure␤»