Independent routines
These routines are defined in different files along with one or several other classes, but are not actually attached to any particular class or role.
routine EVAL
proto EVAL($code where Blob|Cool|Callable, Str() :$lang = 'Raku',
PseudoStash :$context, Str() :$filename, Bool() :$check, *%_)
multi EVAL($code, Str :$lang where { ($lang // '') eq 'Perl5' },
PseudoStash :$context, Str() :$filename, :$check)
This routine executes at runtime a fragment of code, $code
, of a given language,
$lang
, which defaults to Raku
.
It coerces Cool $code
to Str. If
$code
is a Blob, it'll be processed using the same encoding as
the $lang
compiler would: for Raku
$lang
, uses utf-8
; for Perl5
,
processes using the same rules as Perl.
This works as-is with a literal string parameter. More complex input, such as a variable or string with embedded code, is illegal by default. This can be overridden in any of several ways:
use MONKEY-SEE-NO-EVAL; # Or...
use MONKEY; # shortcut that turns on all MONKEY pragmas
use Test;
my $init = 0;
my $diff = 10;
my Str $changer = '$init += ' ~ $diff; # contains a Str object with value '$init += 10'
# any of the above allows:
EVAL $changer;
EVAL $changer;
say $init; # OUTPUT: «20»
In case the MONKEY-SEE-NO-EVAL
pragma is not activated, the compiler will
complain with EVAL is a very dangerous function!!!
. And it is
essentially right, since that will run arbitrary code with the same permissions
as the program. You should take care of cleaning the code that is going to pass
through EVAL if you activate the MONKEY-SEE-NO-EVAL
pragma.
Please note that you can interpolate to create routine names using quotation, as can be seen in this example or other ways to interpolate to create identifier names. This only works, however, for already declared functions and other objects and is thus safer to use.
Symbols in the current lexical scope are visible to code in an EVAL
.
my $answer = 42;
EVAL 'say $answer;'; # OUTPUT: «42»
However, since the set of symbols in a lexical scope is immutable after
compile time, an EVAL
can never introduce symbols into the surrounding
scope.
EVAL 'my $lives = 9'; say $lives; # error, $lives not declared
Furthermore, the EVAL
is evaluated in the current package:
module M {
EVAL 'our $answer = 42'
}
say $M::answer; # OUTPUT: «42»
And also in the current language, meaning any added syntax is available:
sub infix:<mean>(*@a) is assoc<list> {
@a.sum / @a.elems
}
EVAL 'say 2 mean 6 mean 4'; # OUTPUT: «4»
An EVAL
statement evaluates to the result of the last statement:
sub infix:<mean>(*@a) is assoc<list> {
@a.sum / @a.elems
}
say EVAL 'say 1; 2 mean 6 mean 4'; # OUTPUT: «14»
EVAL
is also a gateway for executing code in other languages:
EVAL "use v5.20; say 'Hello from perl!'", :lang<Perl5>;
You need to have Inline::Perl5 for this to work correctly.
More languages may be supported with additional modules which may be found from the Raku Modules Directory.
If the optional $filename
parameter is given, the
$?FILE variable is set to
its value. Otherwise $?FILE
is set to a unique and generated file name.
use MONKEY-SEE-NO-EVAL;
EVAL 'say $?FILE'; # OUTPUT: «/tmp/EVAL_0»
EVAL 'say $?FILE', filename => '/my-eval-code'; # OUTPUT: «/my-eval-code»
If the optional $check
parameter is True
, $code
is processed by the $lang
compiler but is not actually
run. For Raku
, BEGIN, and
CHECK blocks are run. The EVAL
routine
then returns Nil if compilation was successful, otherwise an exception
is thrown.
sub EVALFILE
sub EVALFILE($filename where Blob|Cool, :$lang = 'Raku', :$check)
Slurps the specified file and evaluates it. Behaves the same way as
EVAL
with regard to Blob decoding, scoping, the $lang
parameter and the $check
parameter. Evaluates to the value produced
by the final statement in the file when $check
is not True
.
EVALFILE "foo.raku";
sub repl
Note: repl
was introduced in release 2021.06 of the Rakudo compiler.
sub repl()
Pauses execution and enters a REPL (read-eval-print loop) in the current
context. This REPL is exactly like the one created when you run raku
without any arguments except that
you can access/modify the program's current context (such as lexical
variables).
For example, if you run this code:
my $name = "Alice";
say "Hello, $name";
repl();
say "Goodbye, $name"
then you'll get the output Hello, Alice
and then enter a REPL session
(before any output with "goodbye" is printed). Your REPL session could
go as follows:
Type 'exit' to leave
[0] > $name
Alice
[1] > $name = "Bob"
Bob
[2] > exit
After exiting the REPL session, Raku will resume running the program;
during this run, any changes you made in the REPL session will still be
in effect. Thus, after the session above, you'd get the output
Goodbye, Bob
rather than Goodbye, Alice
as you would have without
the REPL session.
sub get
multi get (IO::Handle:D $fh = $*ARGFILES) { $fh.get }
This routine is a wrapper for the method of the same name in IO::Handle.
If no Handle
is specified, defaults to $*ARGFILES.
sub getc
multi getc (IO::Handle:D $fh = $*ARGFILES) { $fh.getc }
This routine is a wrapper for the method of the same name in IO::Handle>.
If no Handle
is specified, defaults to $*ARGFILES.
sub mkdir
sub mkdir(IO() $path, Int() $mode = 0o777 --> IO::Path:D)
Creates a new directory; see mode for explanation and
valid values for $mode
. Returns the IO::Path object pointing to
the newly created directory on success;
fails with X::IO::Mkdir if directory cannot be created.
Also creates parent directories, as needed (similar to *nix utility
mkdir
with -p
option); that is, mkdir "foo/bar/ber/meow"
will
create foo
, foo/bar
, and foo/bar/ber
directories if they do not
exist, as well as foo/bar/ber/meow
.
sub chdir
sub chdir(IO() $path, :$d = True, :$r, :$w, :$x --> IO::Path:D)
Changes value of $*CWD
variable to the provided $path
, optionally ensuring
the new path passes several file tests. NOTE: that this routine does NOT
alter the process's current directory (see
&*chdir).
Returns IO::Path
representing new $*CWD
on success. On failure, returns
Failure and leaves $*CWD
untouched.
The $path
can be any object with an IO method that returns an
IO::Path object. The available file tests are:
:d
— check .d returnsTrue
:r
— check .r returnsTrue
:w
— check .w returnsTrue
:x
— check .x returnsTrue
By default, only :d
test is performed.
chdir '/tmp'; # change $*CWD to '/tmp' and check its .d is True
chdir :r, :w, '/tmp'; # … check its .r and .w are True
chdir '/not-there'; # returns Failure
Note that the following construct is a mistake:
# WRONG! DO NOT DO THIS!
my $*CWD = chdir '/tmp/';
Use indir instead.
sub &*chdir
PROCESS::<&chdir> = sub (IO() $path --> IO::Path:D) { }
Changes value of $*CWD
variable to the provided $path
and sets
the process's current directory to the value of
$path.absolute. NOTE: that in most cases,
you want to use chdir routine instead.
Returns an IO::Path
representing the new $*CWD
on success. On failure, returns
Failure and leaves $*CWD
untouched.
The $path
can be any object with an IO method that returns an
IO::Path object.
Note that unlike regular chdir, there are no arguments to specify which file tests to perform.
&*chdir('/tmp'); # change $*CWD and process's current directory to '/tmp'
&*chdir('/not-there'); # returns Failure
Note that the following construct is a mistake:
# WRONG! DO NOT DO THIS!
my $*CWD = &*chdir('/tmp');
Use the following, instead; or see indir if you do not need to change process's current directory:
temp $*CWD;
&*chdir('/tmp');
sub chmod
sub chmod(Int() $mode, *@filenames --> List)
Coerces all @filenames
to IO::Path and calls
IO::Path.chmod with $mode
on them.
Returns a List containing a subset of @filenames
for which
chmod
was successfully executed.
chmod 0o755, <myfile1 myfile2>; # make two files executable by the owner
sub indir
sub indir(IO() $path, &code, :$d = True, :$r, :$w, :$x)
Takes Callable &code
and executes it after locally (to
&code
) changing $*CWD
variable to an IO::Path object based on $path
,
optionally ensuring the new path passes several file tests. If $path
is
relative, it will be turned into an absolute path, even if an IO::Path
object was given. NOTE: that this routine does NOT alter the process's
current directory (see &*chdir). The $*CWD
outside of the &code
is not affected, even if &code
explicitly assigns
a new value to $*CWD
.
Returns the value returned by the &code
call on success. On failure to
successfully change $*CWD
, returns Failure.
WARNING: keep in mind that lazily evaluated things might end up NOT
having the $*CWD
set by indir
in their dynamic scope by the time
they're actually evaluated. Either ensure the generators have their
$*CWD
set or eagerly evaluate them before returning
the results from indir
:
say indir("/tmp", {
gather { take ".".IO }
})».CWD; # OUTPUT: «(/home/camelia)»
say indir("/tmp", {
eager gather { take ".".IO }
})».CWD; # OUTPUT: «(/tmp)»
say indir("/tmp", {
my $cwd = $*CWD;
gather { temp $*CWD = $cwd; take ".".IO }
})».CWD; # OUTPUT: «(/tmp)»
The routine's $path
argument can be any object with an IO method that
returns an IO::Path object. The available file
tests are:
:d
— check .d returnsTrue
:r
— check .r returnsTrue
:w
— check .w returnsTrue
:x
— check .x returnsTrue
By default, only :d
test is performed.
say $*CWD; # OUTPUT: «"/home/camelia".IO»
indir '/tmp', { say $*CWD }; # OUTPUT: «"/tmp".IO»
say $*CWD; # OUTPUT: «"/home/camelia".IO»
indir '/not-there', {;}; # returns Failure; path does not exist
sub print
multi print(**@args --> True)
multi print(Junction:D --> True)
Prints the given text on standard output (the $*OUT filehandle), coercing non-Str objects to Str by calling .Str method. Junction arguments autothread and the order of printed strings is not guaranteed.
print "Hi there!\n"; # OUTPUT: «Hi there!»
print "Hi there!"; # OUTPUT: «Hi there!»
print [1, 2, 3]; # OUTPUT: «1 2 3»
print "Hello" | "Goodbye"; # OUTPUT: «HelloGoodbye»
To print text and include the trailing newline, use put.
sub put
multi put()
multi put(**@args --> True)
multi put(Junction:D --> True)
multi put(Str:D \x)
multi put(\x)
Same as print, except it uses print-nl (which prints a newline, by default) at the end. Junction arguments autothread and the order of printed strings is not guaranteed.
put "Hi there!\n"; # OUTPUT: «Hi there!»
put "Hi there!"; # OUTPUT: «Hi there!»
put [1, 2, 3]; # OUTPUT: «1 2 3»
put "Hello" | "Goodbye"; # OUTPUT: «HelloGoodbye»
By itself, put()
will print a new line
put "Hey"; put(); put("Hey"); # OUTPUT: «HeyHey»
but please note that we have used parentheses after put
. Without these
parentheses, it will throw an exception (with version 6.d and after). It will
also raise an exception if it's used that way before for
; use the method form
.put
instead.
.put for <1 2 3>; # OUTPUT: «123»
sub say
multi say(**@args --> True)
Prints the "gist" of given objects; it will always invoke .gist
in the
case the object is a subclass of Str. Same as
put,
except it uses .gist method to obtain string
representation of the object; as in the case of put
, it will also
autothread for Junctions.
NOTE: the .gist method of some objects, such as Lists, returns only partial information about the object (hence the "gist"). If you mean to print textual information, you most likely want to use put instead.
say Range; # OUTPUT: «(Range)»
say class Foo {}; # OUTPUT: «(Foo)»
say 'I ♥ Raku'; # OUTPUT: «I ♥ Raku»
say 1..Inf; # OUTPUT: «1..Inf»
routine note
method note(Mu: -->Bool:D)
multi note( --> Bool:D)
multi note(Str:D $note --> Bool:D)
multi note(**@args --> Bool:D)
Like say (in the sense it will invoke the .gist
method
of the printed object), except it prints output to
$*ERR handle (STDERR
).
If no arguments are given to subroutine forms, will use string "Noted"
.
note; # STDERR OUTPUT: «Noted»
note 'foo'; # STDERR OUTPUT: «foo»
note 1..*; # STDERR OUTPUT: «1..Inf»
This command will also autothread on Junctions, and is guaranteed to call
gist
on the object if it's a subclass of Str.
sub prompt
multi prompt()
multi prompt($msg)
Prints $msg
to $*OUT
handle if $msg
was provided,
then gets a line of input from $*IN
handle. By default, this
is equivalent to printing $msg
to
STDOUT,
reading a line from
STDIN,
removing the trailing new line, and returning the resultant string. As of Rakudo
2018.08, prompt
will create allomorphs for
numeric values, equivalent to calling val prompt
.
my $name = prompt "What's your name? ";
say "Hi, $name! Nice to meet you!";
my $age = prompt("Say your age (number)");
my Int $years = $age;
my Str $age-badge = $age;
In the code above, $age
will be duck-typed to the allomorph IntStr if it's
entered correctly as a number.
sub open
multi open(IO() $path, |args --> IO::Handle:D)
Creates a handle with the given $path
, and calls
IO::Handle.open, passing any of the
remaining arguments to it. Note that IO::Path type provides numerous
methods for reading and writing from files, so in many common cases you
do not need to open
files or deal with IO::Handle type directly.
my $fh = open :w, '/tmp/some-file.txt';
$fh.say: 'I ♥ writing Raku code';
$fh.close;
$fh = open '/tmp/some-file.txt';
print $fh.readchars: 4;
$fh.seek: 7, SeekFromCurrent;
say $fh.readchars: 4;
$fh.close;
# OUTPUT: «I ♥ Raku»
sub slurp
multi slurp(IO::Handle:D $fh = $*ARGFILES, |c)
multi slurp(IO() $path, |c)
Slurps the contents of the entire file into a Str (or Buf if
:bin
). Accepts :bin
and :enc
optional named parameters, with
the same meaning as open(); possible encodings are the
same as in all the other IO methods and are listed in
encoding routine. The routine
will fail
if the file does not exist, or is a directory. Without any
arguments, sub slurp
operates on $*ARGFILES
, which defaults to
$*IN
in the absence of any filenames.
# read entire file as (Unicode) Str
my $text_contents = slurp "path/to/file";
# read entire file as Latin1 Str
my $text_contents = slurp "path/to/file", enc => "latin1";
# read entire file as Buf
my $binary_contents = slurp "path/to/file", :bin;
sub spurt
multi spurt(IO() $path, |c)
The $path
can be any object with an IO method that returns an
IO::Path object. Calls IO::Path.spurt
on the $path
, forwarding any of the remaining arguments.
Options
:enc
The encoding with which the contents will be written.
:append
Boolean indicating whether to append to a (potentially) existing file. If
the file did not exist yet, it will be created. Defaults to False
.
:createonly
Boolean indicating whether to fail if the file already exists. Defaults to
False
.
Examples
# write directly to a file
spurt 'path/to/file', 'default text, directly written';
# write directly with a non-Unicode encoding
spurt 'path/to/latin1_file', 'latin1 text: äöüß', :enc<latin1>;
spurt 'file-that-already-exists', 'some text'; # overwrite file's contents:
spurt 'file-that-already-exists', ' new text', :append; # append to file's contents:
say slurp 'file-that-already-exists'; # OUTPUT: «some text new text»
# fail when writing to a pre-existing file
spurt 'file-that-already-exists', 'new text', :createonly;
# OUTPUT: «Failed to open file /home/camelia/file-that-already-exists: file already exists …»
multi spurt(IO() $path)
As of the 2020.12 release of the Rakudo compiler, it is also possible
to call the spurt
subroutine without any data. This will either
create an empty file, or will truncate any existing file at the given
path.
# create an empty file / truncate a file
spurt 'path/to/file';
sub run
sub run(
*@args ($, *@),
:$in = '-',
:$out = '-',
:$err = '-',
Bool :$bin = False,
Bool :$chomp = True,
Bool :$merge = False,
Str:D :$enc = 'UTF-8',
Str:D :$nl = "\n",
:$cwd = $*CWD,
Hash() :$env = %*ENV,
:$arg0,
:$win-verbatim-args = False
--> Proc:D)
Runs an external command without involving a shell and returns a Proc object. By default, the external command will print to standard output and error, and read from standard input.
run 'touch', '--', '*.txt'; # Create a file named “*.txt”
run <rm -- *.txt>; # Another way to use run, using word quoting for the
# arguments
If you want to pass some variables you can still use < >
, but try
to avoid using « »
as it will do word splitting if you forget to
quote variables:
my $file = ‘--my arbitrary filename’;
run ‘touch’, ‘--’, $file; # RIGHT
run <touch -->, $file; # RIGHT
run «touch -- "$file"»; # RIGHT but WRONG if you forget quotes
run «touch -- $file»; # WRONG; touches ‘--my’, ‘arbitrary’ and ‘filename’
run ‘touch’, $file; # WRONG; error from `touch`
run «touch "$file"»; # WRONG; error from `touch`
Note that --
is required for many programs to disambiguate between
command-line arguments and
filenames that begin with hyphens.
A sunk Proc object for a process that exited unsuccessfully will throw. If you wish to ignore such failures, simply use run in non-sink context:
run 'false'; # SUNK! Will throw
run('false').so; # OK. Evaluates Proc in Bool context; no sinking
If you want to capture standard output or error instead of having it printed
directly you can use the :out
or :err
arguments, which will make them
available using their respective methods: Proc.out and
Proc.err.
my $proc = run 'echo', 'Raku is Great!', :out, :err;
$proc.out.slurp(:close).say; # OUTPUT: «Raku is Great!»
$proc.err.slurp(:close).say; # OUTPUT: «»
You can use these arguments to redirect them to a filehandle, thus creating a kind of pipe:
my $ls-alt-handle = open :w, '/tmp/cur-dir-ls-alt.txt';
my $proc = run "ls", "-alt", :out($ls-alt-handle);
# (The file will contain the output of the ls -alt command)
These argument are quite flexible and admit, for instance, handles to redirect them. See Proc and Proc::Async for more details.
See also new and spawn for more examples and explanation of all arguments.
sub shell
multi shell($cmd, :$in = '-', :$out = '-', :$err = '-',
Bool :$bin, Bool :$chomp = True, Bool :$merge,
Str :$enc, Str:D :$nl = "\n", :$cwd = $*CWD, :$env)
Runs a command through the system shell, which defaults to %*ENV<ComSpec> /c
in Windows, /bin/sh -c
otherwise. All shell metacharacters are interpreted by
the shell, including pipes, redirects, environment variable substitutions and so
on. Shell escapes are a severe security concern and can cause confusion with
unusual file names. Use run if you want to be safe.
The return value is of type Proc.
shell 'ls -lR | gzip -9 > ls-lR.gz';
See Proc for more details, for example on how to capture output.
routine unpolar
method unpolar(Real $angle)
multi unpolar(Real $mag, Real $angle)
Returns a Complex with the coordinates corresponding to the angle in
radians and magnitude corresponding to the object value or $mag
in
the case it's being used as a sub
say 1.unpolar(⅓*pi);
# OUTPUT: «0.5000000000000001+0.8660254037844386i»
routine printf
multi printf(Cool:D $format, *@args)
Produces output according to a format. The format used is the invocant (if called in method form) or the first argument (if called as a routine). The rest of the arguments will be substituted in the format following the format conventions. See sprintf for details on acceptable format directives.
"%s is %s".printf("þor", "mighty"); # OUTPUT: «þor is mighty»
printf( "%s is %s", "þor", "mighty"); # OUTPUT: «þor is mighty»
On Junctions, it will also autothread, without a guaranteed order.
printf( "%.2f ", ⅓ | ¼ | ¾ ); # OUTPUT: «0.33 0.25 0.75 »
routine sprintf
multi sprintf(Cool:D $format, *@args)
Returns a string according to a format as described below. The format used is the invocant (if called in method form) or the first argument (if called as a routine).
sprintf( "%s the %d%s", "þor", 1, "st").put; # OUTPUT: «þor the 1st»
sprintf( "%s is %s", "þor", "mighty").put; # OUTPUT: «þor is mighty»
"%s's weight is %.2f %s".sprintf( "Mjölnir", 3.3392, "kg").put;
# OUTPUT: «Mjölnir's weight is 3.34 kg»
# OUTPUT: «Mjölnir's weight is 3.34 kg»
This function is mostly identical to the C library's sprintf
and printf
functions. The only difference between the two functions is that sprintf
returns a string while the printf
function writes to a filehandle. sprintf
returns a Str, not a literal.
The $format
is scanned for %
characters. Any %
introduces a
format token. Directives guide the use (if any) of the arguments. When
a directive other than %
is used, it indicates how the next
argument passed is to be formatted into the string to be
created. Parameter indexes may also be used in the format
tokens. They take the form N$
and are explained in more detail
below.
The $format
may be defined enclosed in single or double quotes. The
double-quoted $format
string is interpolated before being scanned
and any embedded string whose interpolated value contains a %
character will cause an exception. For example:
my $prod = "Ab-%x-42";
my $cost = "30";
sprintf("Product $prod; cost: \$%d", $cost).put;
# OUTPUT: «Your printf-style directives specify 2 arguments, but 1 argument was supplied»
« in block <unit> at <unknown file> line 1»
When handling unknown input you should avoid using such syntax by
putting all variables in the *@args
array and have one %
for each
in $format
. If you need to include a $
symbol in the format
string (even as a parameter index) either escape it or use the
single-quoted form. For example, either of the following forms works
without error:
sprintf("2 x \$20 = \$%d", 2*20).put; # OUTPUT: «2 x $20 = $40»
sprintf('2 x $20 = $%d', 2*20).put; # OUTPUT: «2 x $20 = $40»
In summary, unless you need something very special, you will have fewer unexpected problems by using the single-quoted format string and not using interpolated strings inside the format string.
Directives
% | a literal percent sign |
c | a character with the given codepoint |
s | a string |
d | a signed integer, in decimal |
u | an unsigned integer, in decimal |
o | an unsigned integer, in octal |
x | an unsigned integer, in hexadecimal |
e | a floating-point number, in scientific notation |
f | a floating-point number, in fixed decimal notation |
g | a floating-point number, in %e or %f notation |
X | like x, but using uppercase letters |
E | like e, but using an uppercase "E" |
G | like g, but with an uppercase "E" (if applicable) |
b | an unsigned integer, in binary |
Compatibility:
i | a synonym for %d |
D | a synonym for %ld |
U | a synonym for %lu |
O | a synonym for %lo |
F | a synonym for %f |
Modifiers
Modifiers change the meaning of format directives, but are largely no-ops (the semantics are still being determined).
h | interpret integer as native "short" (typically int16) | |
NYI | l | interpret integer as native "long" (typically int32 or int64) |
NYI | ll | interpret integer as native "long long" (typically int64) |
NYI | L | interpret integer as native "long long" (typically uint64) |
NYI | q | interpret integer as native "quads" (typically int64 or larger) |
Between the %
and the format letter, you may specify several
additional attributes controlling the interpretation of the format. In
order, these are:
NYI Format parameter index using the '$' symbol
An explicit format parameter index (ranging from 1 to N args)
before the directive, such as %2$d
. By default, sprintf
will
format the next unused argument in the list, but the parameter index
allows you to take the arguments out of order (note single quotes
are required unless you escape the $
):
Without index:
sprintf '%d %d', 12, 34; # OUTPUT: «12 34»
sprintf '%d %d %d', 1, 2, 3; # OUTPUT: «1 2 3»
NYI With index:
The first example works as we expect it to when we index all directives.
sprintf '%2$d %1$d', 12, 34; # OUTPUT: «34 12»
But notice the effect when mixing indexed and non-indexed directives in the second example (be careful what you ask for). The second, non-indexed directive gets the first argument, but it is also specifically requested in the last directive:
sprintf '%3$d %d %1$d', 1, 2, 3; # OUTPUT: «3 1 1»
Flags
One or more of:
space | prefix non-negative number with a space |
\+ | prefix non-negative number with a plus sign |
- | left-justify within the field |
0 | use leading zeros, not spaces, for required padding |
# | ensure the leading "0" for any octal, |
prefix non-zero hexadecimal with "0x" or "0X", | |
prefix non-zero binary with "0b" or "0B" | |
v | NYI vector flag (used only with directive "d"), see description below |
For example:
sprintf '<% d>', 12; # OUTPUT: «< 12>»
sprintf '<% d>', 0; # OUTPUT: «< 0>"»
sprintf '<% d>', -12; # OUTPUT: «<-12>»
sprintf '<%+d>', 12; # OUTPUT: «<+12>»
sprintf '<%+d>', 0; # OUTPUT: «<+0>"»
sprintf '<%+d>', -12; # OUTPUT: «<-12>»
sprintf '<%6s>', 12; # OUTPUT: «< 12>»
sprintf '<%-6s>', 12; # OUTPUT: «<12 >»
sprintf '<%06s>', 12; # OUTPUT: «<000012>»
sprintf '<%#o>', 12; # OUTPUT: «<014>»
sprintf '<%#x>', 12; # OUTPUT: «<0xc>»
sprintf '<%#X>', 12; # OUTPUT: «<0XC>»
sprintf '<%#b>', 12; # OUTPUT: «<0b1100>»
sprintf '<%#B>', 12; # OUTPUT: «<0B1100>»
When a space and a plus sign are given as the flags at once, the space is ignored:
sprintf '<%+ d>', 12; # OUTPUT: «<+12>»
sprintf '<% +d>', 12; # OUTPUT: «<+12>»
When the #
flag and a precision are given in the %o
conversion, the
necessary number of 0s is added at the beginning. If the value of the number is
0
and the precision is 0, it will output nothing; precision 0 or smaller than
the actual number of elements will return the number with 0 to the left:
say sprintf '<%#.5o>', 0o12; # OUTPUT: «<00012>»
say sprintf '<%#.5o>', 0o12345; # OUTPUT: «<012345>»
say sprintf '<%#.0o>', 0; # OUTPUT: «<>» zero precision and value 0
# results in no output!
say sprintf '<%#.0o>', 0o1 # OUTPUT: «<01>»
Vector flag 'v'
This special flag (v
, followed by directive d
) tells Raku to
interpret the supplied string as a vector of integers, one for each
character in the string (the `ord` routine is used for the conversion
to an integer). Raku applies the format to each integer in turn, then
joins the resulting strings with a separator (a dot '.'
, by
default). This can be useful for displaying ordinal values of
characters in arbitrary strings:
NYI sprintf "%vd", "AB\x[100]"; # OUTPUT: «65.66.256»
You can also explicitly specify the argument number to use for the
separator string by using an asterisk with a parameter index (e.g.,
*2$v
); for example:
NYI sprintf '%*4$vX %*4$vX %*4$vX', # 3 IPv6 addresses
@addr[1..3], ":";
Width (minimum)
Arguments are usually formatted by default to be only as wide as required to
display the given value. You specify a minimum width that can override the default width by putting a
number here, or get the desired width from the next argument (with *
) or
from a specified argument (e.g., with *2$
):
sprintf "<%s>", "a"; # OUTPUT: «<a>»
sprintf "<%6s>", "a"; # OUTPUT: «< a>»
sprintf "<%*s>", 6, "a"; # OUTPUT: «< a>»
NYI sprintf '<%*2$s>', "a", 6; # OUTPUT: «< a>»
sprintf "<%2s>", "long"; # OUTPUT: «<long>» (does not truncate)
In all cases, the specified width will be increased as necessary to accommodate the given integral numerical value or string.
If a field width obtained through *
is negative, it has the same
effect as the -
flag: left-justification.
Precision, or maximum width
You can specify a precision (for numeric conversions) or a maximum
width (for string conversions) by specifying a .
followed by a
number. For floating-point formats, except g
and G
, this
specifies how many places right of the decimal point to show (the
default being 6). For example:
# These examples are subject to system-specific variation.
sprintf '<%f>', 1; # OUTPUT: «"<1.000000>"»
sprintf '<%.1f>', 1; # OUTPUT: «"<1.0>"»
sprintf '<%.0f>', 1; # OUTPUT: «"<1>"»
sprintf '<%e>', 10; # OUTPUT: «"<1.000000e+01>"»
sprintf '<%.1e>', 10; # OUTPUT: «"<1.0e+01>"»
For "g" and "G", this specifies the maximum number of digits to show, including those prior to the decimal point and those after it; for example:
# These examples are subject to system-specific variation.
sprintf '<%g>', 1; # OUTPUT: «<1>»
sprintf '<%.10g>', 1; # OUTPUT: «<1>»
sprintf '<%g>', 100; # OUTPUT: «<100>»
sprintf '<%.1g>', 100; # OUTPUT: «<1e+02>»
sprintf '<%.2g>', 100.01; # OUTPUT: «<1e+02>»
sprintf '<%.5g>', 100.01; # OUTPUT: «<100.01>»
sprintf '<%.4g>', 100.01; # OUTPUT: «<100>»
For integer conversions, specifying a precision implies the
output of the number itself should be zero-padded to this width (where
the 0
flag is ignored):
(Note that this feature currently works for unsigned integer conversions, but not for signed integer.)
sprintf '<%.6d>', 1; # OUTPUT: «<000001>»
NYI sprintf '<%+.6d>', 1; # OUTPUT: «<+000001>»
NYI sprintf '<%-10.6d>', 1; # OUTPUT: «<000001 >»
sprintf '<%10.6d>', 1; # OUTPUT: «< 000001>»
NYI sprintf '<%010.6d>', 1; # OUTPUT: «< 000001>»
NYI sprintf '<%+10.6d>', 1; # OUTPUT: «< +000001>»
sprintf '<%.6x>', 1; # OUTPUT: «<000001>»
sprintf '<%#.6x>', 1; # OUTPUT: «<0x000001>»
sprintf '<%-10.6x>', 1; # OUTPUT: «<000001 >»
sprintf '<%10.6x>', 1; # OUTPUT: «< 000001>»
sprintf '<%010.6x>', 1; # OUTPUT: «< 000001>»
sprintf '<%#10.6x>', 1; # OUTPUT: «< 0x000001>»
For string conversions, specifying a precision truncates the string to fit the specified width:
sprintf '<%.5s>', "truncated"; # OUTPUT: «<trunc>» sprintf '<%10.5s>', "truncated"; # OUTPUT: «< trunc>»
You can also get the precision from the next argument using .*
, or
from a specified argument (e.g., with .*2$
):
sprintf '<%.6x>', 1; # OUTPUT: «<000001>»
sprintf '<%.*x>', 6, 1; # OUTPUT: «<000001>»
NYI sprintf '<%.*2$x>', 1, 6; # OUTPUT: «<000001>»
NYI sprintf '<%6.*2$x>', 1, 4; # OUTPUT: «< 0001>»
If a precision obtained through *
is negative, it counts as having
no precision at all:
sprintf '<%.*s>', 7, "string"; # OUTPUT: «<string>» sprintf '<%.*s>', 3, "string"; # OUTPUT: «<str>» sprintf '<%.*s>', 0, "string"; # OUTPUT: «<>» sprintf '<%.*s>', -1, "string"; # OUTPUT: «<string>» sprintf '<%.*d>', 1, 0; # OUTPUT: «<0>» sprintf '<%.*d>', 0, 0; # OUTPUT: «<>» sprintf '<%.*d>', -1, 0; # OUTPUT: «<0>»
Size
For numeric conversions, you can specify the size to interpret the
number as using l
, h
, V
, q
, L
, or ll
. For integer
conversions (d
u
o
x
X
b
i
D
U
O
),
numbers are usually assumed to be whatever the default integer size is
on your platform (usually 32 or 64 bits), but you can override this to
use instead one of the standard C types, as supported by the compiler
used to build Raku:
(Note: None of the following have been implemented.)
hh | interpret integer as C type "char" or "unsigned char" |
h | interpret integer as C type "short" or "unsigned short" |
j | interpret integer as C type "intmax_t", only with a C99 compiler (unportable) |
l | interpret integer as C type "long" or "unsigned long" |
q, L, or ll | interpret integer as C type "long long", "unsigned long long", or "quad" (typically 64-bit integers) |
t | interpret integer as C type "ptrdiff_t" |
z | interpret integer as C type "size_t" |
Order of arguments
Normally, sprintf
takes the next unused argument as the value to
format for each format specification. If the format specification uses
*
to require additional arguments, these are consumed from the
argument list in the order they appear in the format specification
before the value to format. Where an argument is specified by an
explicit index, this does not affect the normal order for the
arguments, even when the explicitly specified index would have been
the next argument.
So:
my $a = 5; my $b = 2; my $c = 'net';
sprintf "<%*.*s>", $a, $b, $c; # OUTPUT: «< ne>»
uses $a
for the width, $b
for the precision, and $c
as the value to
format; while:
NYI sprintf '<%*1$.*s>', $a, $b;
would use $a
for the width and precision and $b
as the value to format.
Here are some more examples; be aware that when using an explicit
index, the $
will need escaping if the format string is double-quoted:
sprintf "%2\$d %d\n", 12, 34; # OUTPUT: «34 12»
sprintf "%2\$d %d %d\n", 12, 34; # OUTPUT: «34 12 34»
sprintf "%3\$d %d %d\n", 12, 34, 56; # OUTPUT: «56 12 34»
NYI sprintf "%2\$*3\$d %d\n", 12, 34, 3; # OUTPUT: « 34 12»
NYI sprintf "%*1\$.*f\n", 4, 5, 10; # OUTPUT: «5.0000»
Other examples:
NYI sprintf "%ld a big number", 4294967295;
NYI sprintf "%%lld a bigger number", 4294967296;
sprintf('%c', 97); # OUTPUT: «a»
sprintf("%.2f", 1.969); # OUTPUT: «1.97»
sprintf("%+.3f", 3.141592); # OUTPUT: «+3.142»
sprintf('%2$d %1$d', 12, 34); # OUTPUT: «34 12»
sprintf("%x", 255); # OUTPUT: «ff»
Special case: sprintf("<b>%s</b>\n", "Raku")
will not work, but
one of the following will:
sprintf Q:b "<b>%s</b>\n", "Raku"; # OUTPUT: «<b>Raku</b>»
sprintf "<b>\%s</b>\n", "Raku"; # OUTPUT: «<b>Raku</b>»
sprintf "<b>%s\</b>\n", "Raku"; # OUTPUT: «<b>Raku</b>»
sub flat
multi flat(**@list)
multi flat(Iterable \a)
Constructs a list which contains any arguments provided, and returns the result
of calling the .flat
method (inherited from Any)
on that list or Iterable:
say flat 1, (2, (3, 4), $(5, 6)); # OUTPUT: «(1 2 3 4 (5 6))»
routine unique
multi unique(+values, |c)
Returns a sequence of unique values from the invocant/argument list, such
that only the first occurrence of each duplicated value remains in the
result list. unique
uses the semantics of the === operator to decide
whether two objects are the same, unless the optional :with
parameter is
specified with another comparator. The order of the original list is preserved
even as duplicates are removed.
Examples:
say <a a b b b c c>.unique; # OUTPUT: «(a b c)»
say <a b b c c b a>.unique; # OUTPUT: «(a b c)»
(Use squish instead if you know the input is sorted such that identical objects are adjacent.)
The optional :as
parameter allows you to normalize/canonicalize the elements
before unique-ing. The values are transformed for the purposes of comparison,
but it's still the original values that make it to the result list; however,
only the first occurrence will show up in that list:
Example:
say <a A B b c b C>.unique(:as(&lc)) # OUTPUT: «(a B c)»
One can also specify the comparator with the optional :with
parameter. For
instance if one wants a list of unique hashes, one could use the eqv
comparator.
Example:
my @list = %(a => 42), %(b => 13), %(a => 42);
say @list.unique(:with(&[eqv])) # OUTPUT: «({a => 42} {b => 13})»
Note: since :with
Callable has to be tried with all the
items in the list, this makes unique
follow a path with much higher
algorithmic complexity. You should try to use the :as
argument instead,
whenever possible.
routine repeated
multi repeated(+values, |c)
This returns a sequence of repeated values from the invocant/argument list. It takes the same parameters as unique, but instead of passing through any elements when they're first seen, they're only passed through as soon as they're seen for the second time (or more).
Examples:
say <a a b b b c c>.repeated; # OUTPUT: «(a b b c)»
say <a b b c c b a>.repeated; # OUTPUT: «(b c b a)»
say <a A B b c b C>.repeated(:as(&lc)); # OUTPUT: «(A b b C)»
my @list = %(a => 42), %(b => 13), %(a => 42);
say @list.repeated(:with(&[eqv])) # OUTPUT: «({a => 42})»
As in the case of unique the associative argument
:as
takes a Callable that normalizes the element before comparison, and
:with
takes a the equality comparison function that is going to be used.
routine squish
sub squish( +values, |c)
Returns a sequence of values from the invocant/argument list where runs of one
or more values are replaced with only the first instance. Like unique,
squish
uses the semantics of the === operator to decide whether two
objects are the same. Unlike unique, this function only removes adjacent
duplicates; identical values further apart are still kept. The order of the
original list is preserved even as duplicates are removed.
Examples:
say <a a b b b c c>.squish; # OUTPUT: «(a b c)»
say <a b b c c b a>.squish; # OUTPUT: «(a b c b a)»
The optional :as
parameter, just like with unique, allows values to be
temporarily transformed before comparison.
The optional :with
parameter is used to set an appropriate comparison
operator:
say [42, "42"].squish; # OUTPUT: «(42 42)»
# Note that the second item in the result is still Str
say [42, "42"].squish(with => &infix:<eq>); # OUTPUT: «(42)»
# The resulting item is Int
sub emit
sub emit(\value --> Nil)
If used outside any supply or react block, throws an exception emit without
supply or react
. Within a Supply block, it will add a message to the stream.
my $supply = supply {
for 1 .. 10 {
emit($_);
}
}
$supply.tap( -> $v { say "First : $v" });
See also the page for emit methods.
sub undefine
multi undefine(Mu \x)
multi undefine(Array \x)
multi undefine(Hash \x)
DEPRECATED in 6.d language version and will be removed in 6.e. For
Array and Hash, it will become equivalent to
assigning Empty; for everything else,
equivalent to assigning Nil or Empty
in the case of arrays or
hashes, whose use is advised.
Array manipulation
Routines that manipulate arrays and other mutable collections.
sub pop
multi pop(@a) is raw
Calls method pop
on the Positional argument. That method is supposed to
remove and return the last element, or return a Failure
wrapping an X::Cannot::Empty if the collection is
empty.
See the documentation of the Array method for an example.
sub shift
multi shift(@a) is raw
Calls method shift
on the Positional argument. That method, on
a mutable collection that actually implements it (such as an
Array or a
Buf), is supposed to remove
and return the first element, or return a Failure if the
collection is empty.
Example:
say shift [1,2]; # OUTPUT: «1»
my @a of Int = [1];
say shift @a; # OUTPUT: «1»
say shift @a; # ERROR: «Cannot shift from an empty Array[Int]»
sub push
multi push(\a, **@b is raw)
multi push(\a, \b)
Calls method push
on the first argument, passing the remaining arguments.
Method push
is supposed to add the provided values to the end of the
collection or parts thereof. See the documentation of the
Hash method for an example where
indirection via this subroutine can be helpful.
The push
method is supposed to flatten all arguments of type Slip.
Therefore, if you want to implement a conforming method for a new collection
type, it should behave as if its signature was just:
multi method push(::?CLASS:D: **@values is raw --> ::?CLASS:D)
Autovivification to an instance of the new type is provided by the default base class if the new type implements the Positional role. If the new type is not Positional, autovivification can be supported by adding a multi method with a signature like
multi method push(::?CLASS:U: **@values is raw --> ::?CLASS:D)
sub append
multi append(\a, **@b is raw)
multi append(\a, \b)
Calls method append
on the first argument, passing the remaining arguments.
Method append
is supposed to add the provided values to the end of the
collection or parts thereof. Unlike method push
, method append
should
follow the single argument rule. So
if you want to implement a conforming method append
for a new collection
type, it should behave as if its signature was just:
multi method append(::?CLASS:D: +values --> ::?CLASS:D)
Similar to routine push, you may need to add a multi method if you want to support autovivification:
multi method append(::?CLASS:U: +values --> ::?CLASS:D)
The subroutine form of append
can be helpful when appending to the values of
a Hash. Whereas method append will
silently ignore literal pairs that are interpreted as named arguments, the
subroutine will throw:
my %h = i => 0;
append %h, i => (1, 42);
CATCH { default { put .message } };
# OUTPUT: «Unexpected named argument 'i' passed»
Control routines
Routines that change the flow of the program, maybe returning a value.
sub exit
multi exit()
multi exit(Int(Any) $status)
Exits the current process with return code $status
or zero if no
value has been specified. The exit value ($status
), when different
from zero, has to be opportunely evaluated from the process that catches
it (e.g., a shell); it is the only way to return an exit code different
from zero from a Main.
exit
prevents the LEAVE phaser to be
executed, but it will run the code in the
&*EXIT variable.
exit
should be used as last resort only to signal the parent process
about an exit code different from zero, and not to terminate
exceptionally a method or a sub: use exceptions
instead.
The first call of exit
in a process sets the return code, regardless
of any subsequent calls to exit
in the same, or any other thread.
sub done
sub done(--> Nil)
If used outside any supply or react block, throws an exception done without
supply or react
. Within a Supply block, it will indicate the
supply will no longer emit anything. See also documentation on method
done.
my $supply = supply {
for 1 .. 3 {
emit($_);
}
done;
}
$supply.tap( -> $v { say "Second : $v" }, done => { say "No more" });
# OUTPUT: «Second : 1Second : 2Second : 3No More»
The block passed to the done
named argument will be run when done
is
called within the supply
block.
As of the 2021.06 release of the Rakudo compiler, it is also possibly to
supply a value with done
:
sub done($value --> Nil)
The specified value will first be emit
ted before an argumentless
done
will be called.
my $supply = supply {
for 1 .. 3 {
emit($_);
}
done 42; # same as: emit 42; done
}
$supply.tap: -> $v { say "Val: $v" }, done => { say "No more" }
# OUTPUT: OUTPUT: «Val: 1Val: 2Val: 3Val: 42No More»
sub lastcall
sub lastcall(--> True)
Truncates the current dispatch chain, which means any calls to
nextsame
, callsame
, nextwith
, and callwith
will not
find any of the next candidates. Note that since samewith
restarts the dispatch from the start, it's not affected by the
truncation of current chain with lastcall
.
Consider example below. foo(6)
uses nextsame
when lastcall
hasn't been called, and so it reaches the Any
candidate. foo(2)
calls nextsame
as well, but since
lastcall
was called first, the dispatch chain was truncated and
the Any candidate was not reached. The last call, foo(1)
,
calls lastcall
too, however, it then uses samewith
, which
isn't affected by it, and so the dispatch re-starts from scratch,
hits the Int candidate with the new argument 6
, and then
proceeds to the Any candidate via nextsame
(which
isn't affected by the lastcall
that was used before the
samewith
was called):
multi foo (Int $_) {
say "Int: $_";
lastcall when *.is-prime;
nextsame when * %% 2;
samewith 6 when * !%% 2;
}
multi foo (Any $x) { say "Any $x" }
foo 6; say '----';
foo 2; say '----';
foo 1;
# OUTPUT:
# Int: 6
# Any 6
# ----
# Int: 2
# ----
# Int: 1
# Int: 6
# Any 6
[1]The information below is for a fully functioning sprintf
implementation
which hasn't been achieved yet. Formats or features not yet implemented are
marked NYI.