Independent routines
Routines not defined within any class or role.
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
Defined as:
proto sub EVAL( where Blob|Cool|Callable, Str() : = 'perl6',PseudoStash :, *)
multi sub EVAL(, Str : where ,PseudoStash :)
This routine coerces Cool $code
to Str. If $code
is a Blob, it'll be processed using the same encoding as the $lang
compiler would: for perl6
$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 pragmasuse Test;# any of the above allows:EVAL "say "; # OUTPUT: «10»
In case the MONKEY-SEE-NO-EVAL
pragma is not activated, the compiler will complain with a EVAL is a very dangerous function!!!
exception. 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 = 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 ; # error, $lives not declared
Furthermore, the EVAL
is evaluated in the current package:
say ::answer; # OUTPUT: «42»
And also in the current language, meaning any added syntax is available:
sub infix:<mean>(*) is assoc<list>EVAL 'say 2 mean 6 mean 4'; # OUTPUT: «4»
An EVAL
statement evaluates to the result of the last statement:
sub infix:<mean>(*) is assoc<list>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 perl5!'", :lang<Perl5>;
You need to have Inline::Perl5
for this to work correctly.
sub EVALFILE
Defined as:
sub EVALFILE( where Blob|Cool, : = 'perl6')
Slurps the specified file and evaluates it. Behaves the same way as EVAL
with regard to Blob decoding, scoping, and the $lang
parameter. Evaluates to the value produced by the final statement in the file.
EVALFILE "foo.p6";
sub mkdir
Defined as:
sub mkdir(IO() , Int() = 0o777 --> IO::Path)
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
Defined as:
sub chdir(IO() , : = True, :, :, : --> IO::Path)
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 Truechdir :r, :w, '/tmp'; # … check its .r and .w are Truechdir '/not-there'; # returns Failure
Note that the following construct is a mistake:
# WRONG! DO NOT DO THIS!my = chdir '/tmp/';
Use indir
instead.
sub &*chdir
Defined as:
PROCESS::<&chdir> = sub (IO() --> IO::Path)
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.
('/tmp'); # change $*CWD and process's current directory to '/tmp'('/not-there'); # returns Failure
Note that the following construct is a mistake:
# WRONG! DO NOT DO THIS!my = ('/tmp');
Use the following, instead; or see indir
if you do not need to change process's current directory:
temp ;('/tmp');
sub chmod
Defined as:
sub chmod(Int() , * --> 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
Defined as:
sub indir(IO() , , : = True, :, :, : --> Mu)
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 return value of &code
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",)».CWD; # OUTPUT: «(/home/camelia)»say indir("/tmp",)».CWD; # OUTPUT: «(/tmp)»say indir("/tmp",)».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 ; # OUTPUT: «"/home/camelia".IO»indir '/tmp', ; # OUTPUT: «"/tmp".IO»say ; # OUTPUT: «"/home/camelia".IO»indir '/not-there', ; # returns Failure; path does not exist
sub print
Defined as:
multi sub print(** --> True)multi sub print(Junction --> 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»
To print text and include the trailing newline, use put
.
sub put
Defined as:
multi sub put(** --> True)multi sub put(Junction --> True)
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»
sub say
Defined as:
multi sub say(** --> True)
Prints the "gist" of given objects. Same as put
, except uses .gist
method to obtain string representation of the object.
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 ; # OUTPUT: «(Foo)»say 'I ♥ Perl6'; # OUTPUT: «I ♥ Perl6»say 1..Inf; # OUTPUT: «1..Inf»
routine note
Defined as:
method note(Mu: -->Bool)multi sub note( --> Bool)multi sub note(Str --> Bool)multi sub note(** --> Bool)
Like say
, except 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»
sub prompt
multi sub prompt()multi sub prompt()
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 = prompt "What's your name? ";say "Hi, $name! Nice to meet you!";my = prompt("Say your age (number)");my Int = ;my Str = ;
In the code above, $age
will be duck-typed to the allomorph IntStr if it's entered correctly as a number.
sub open
multi sub open(IO() , |args --> IO::Handle)
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 = open :w, '/tmp/some-file.txt';.say: 'I ♥ writing Perl code';.close;= open '/tmp/some-file.txt';print .readchars: 4;.seek: 7, SeekFromCurrent;say .readchars: 4;.close;# OUTPUT: «I ♥ Perl»
sub slurp
Defined as:
multi sub slurp(IO::Handle = , |c)multi sub slurp(IO() , |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) Strmy = slurp "path/to/file";# read entire file as Latin1 Strmy = slurp "path/to/file", enc => "latin1";# read entire file as Bufmy = slurp "path/to/file", :bin;
sub spurt
Defined as:
multi spurt(IO() , |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 filespurt 'path/to/file', 'default text, directly written';# write directly with a non-Unicode encodingspurt '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 filespurt 'file-that-already-exists', 'new text', :createonly;# OUTPUT: «Failed to open file /home/camelia/file-that-already-exists: file already exists …»
sub run
Defined as:
sub run(* ($, *@),: = '-',: = '-',: = '-',Bool : = False,Bool : = True,Bool : = False,Str : = 'UTF-8',Str : = "\n",: = ,Hash() : =--> Proc)
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', '>foo.txt'; # Create a file named >foo.txtrun <<rm >foo.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 = ‘--my arbitrary filename’;run ‘touch’, ‘--’, ; # RIGHTrun <touch -->, ; # RIGHTrun «touch -- "$file"»; # RIGHT but WRONG if you forget quotesrun «touch -- »; # WRONG; touches ‘--my’, ‘arbitrary’ and ‘filename’run ‘touch’, ; # 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 throwrun('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 = run 'echo', 'Perl 6 is Great!', :out, :err;.out.slurp(:close).say; # OUTPUT: «Perl 6 is Great!».err.slurp(:close).say; # OUTPUT: «»
You can use these arguments to redirect them to a filehandle, thus creating a kind of pipe:
my = open :w, '/tmp/cur-dir-ls-alt.txt';my = run "ls", "-alt", :out();# (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
for more examples.
sub shell
multi sub shell(, : = '-', : = '-', : = '-',Bool :, Bool : = True, Bool :,Str :, Str : = "\n", : = , :)
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
Defined as:
method unpolar(Real )multi sub unpolar(Real , Real )
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
Defined as:
method printf (*)multi sub printf(Cool , *)
As a method, takes the object as a format using the same language as Str.sprintf
; as a sub, its first argument will be the format string, and the rest of the arguments will be substituted in the format following the format conventions.
"%s is %s".printf("þor", "mighty"); # OUTPUT: «þor is mighty»printf( "%s is %s", "þor", "mighty"); # OUTPUT: «þor is mighty»
routine sprintf
Defined as:
method sprintf(*)multi sub sprintf(Cool , *)
Formats and outputs a string, following the same language as Str.sprintf
, using as such format either the object (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»
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.
The directives are:
% | 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 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:
Format parameter index
An explicit format parameter index, such as 2$
. By default, sprintf
will format the next unused argument in the list, but this allows you to take the arguments out of order:
sprintf '%2$d %1$d', 12, 34; # OUTPUT: «34 12»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" |
For example:
sprintf '<% d>', 12; # RESULT: «< 12>»sprintf '<% d>', 0; # RESULT: «< 0>"»sprintf '<% d>', -12; # RESULT: «<-12>»sprintf '<%+d>', 12; # RESULT: «<+12>»sprintf '<%+d>', 0; # RESULT: «<+0>"»sprintf '<%+d>', -12; # RESULT: «<-12>»sprintf '<%6s>', 12; # RESULT: «< 12>»sprintf '<%-6s>', 12; # RESULT: «<12 >»sprintf '<%06s>', 12; # RESULT: «<000012>»sprintf '<%#o>', 12; # RESULT: «<014>»sprintf '<%#x>', 12; # RESULT: «<0xc>»sprintf '<%#X>', 12; # RESULT: «<0XC>»sprintf '<%#b>', 12; # RESULT: «<0b1100>»sprintf '<%#B>', 12; # RESULT: «<0B1100>»
When a space and a plus sign are given as the flags at once, the space is ignored:
sprintf '<%+ d>', 12; # RESULT: «<+12>»sprintf '<% +d>', 12; # RESULT: «<+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
This flag tells Perl 6 to interpret the supplied string as a vector of integers, one for each character in the string. Perl 6 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]"; # "65.66.256"
You can also explicitly specify the argument number to use for the join string using something like *2$v
; for example:
NYI sprintf '%*4$vX %*4$vX %*4$vX', # 3 IPv6 addresses[1..3], ":";
(Minimum) Width
Arguments are usually formatted to be only as wide as required to display the given value. You can override the width by putting a number here, or get the width from the next argument (with *
) or from a specified argument (e.g., with *2$
):
sprintf "<%s>", "a"; # RESULT: «<a>»sprintf "<%6s>", "a"; # RESULT: «< a>»sprintf "<%*s>", 6, "a"; # RESULT: «< a>»NYI sprintf '<%*2$s>', "a", 6; # "< a>"sprintf "<%2s>", "long"; # RESULT: «<long>» (does not truncate)
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 variationsprintf '<%f>', 1; # RESULT: «"<1.000000>"»sprintf '<%.1f>', 1; # RESULT: «"<1.0>"»sprintf '<%.0f>', 1; # RESULT: «"<1>"»sprintf '<%e>', 10; # RESULT: «"<1.000000e+01>"»sprintf '<%.1e>', 10; # RESULT: «"<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; # RESULT: «<1>»sprintf '<%.10g>', 1; # RESULT: «<1>»sprintf '<%g>', 100; # RESULT: «<100>»sprintf '<%.1g>', 100; # RESULT: «<1e+02>»sprintf '<%.2g>', 100.01; # RESULT: «<1e+02>»sprintf '<%.5g>', 100.01; # RESULT: «<100.01>»sprintf '<%.4g>', 100.01; # RESULT: «<100>»
For integer conversions, specifying a precision implies that 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; # <000001>NYI sprintf '<%+.6d>', 1; # <+000001>NYI sprintf '<%-10.6d>', 1; # <000001 >sprintf '<%10.6d>', 1; # < 000001>NYI sprintf '<%010.6d>', 1; # 000001>NYI sprintf '<%+10.6d>', 1; # < +000001>sprintf '<%.6x>', 1; # RESULT: «<000001>»sprintf '<%#.6x>', 1; # RESULT: «<0x000001>»sprintf '<%-10.6x>', 1; # RESULT: «<000001 >»sprintf '<%10.6x>', 1; # RESULT: «< 000001>»sprintf '<%010.6x>', 1; # RESULT: «< 000001>»sprintf '<%#10.6x>', 1; # RESULT: «< 0x000001>»
For string conversions, specifying a precision truncates the string to fit the specified width:
sprintf '<%.5s>', "truncated"; # RESULT: «<trunc>»sprintf '<%10.5s>', "truncated"; # RESULT: «< trunc>»
You can also get the precision from the next argument using .*
, or from a specified argument (e.g., with .*2$
):
sprintf '<%.6x>', 1; # RESULT: «<000001>»sprintf '<%.*x>', 6, 1; # RESULT: «<000001>»NYI sprintf '<%.*2$x>', 1, 6; # "<000001>"NYI sprintf '<%6.*2$x>', 1, 4; # "< 0001>"
If a precision obtained through *
is negative, it counts as having no precision at all:
sprintf '<%.*s>', 7, "string"; # RESULT: «<string>»sprintf '<%.*s>', 3, "string"; # RESULT: «<str>»sprintf '<%.*s>', 0, "string"; # RESULT: «<>»sprintf '<%.*s>', -1, "string"; # RESULT: «<string>»sprintf '<%.*d>', 1, 0; # RESULT: «<0>»sprintf '<%.*d>', 0, 0; # RESULT: «<>»sprintf '<%.*d>', -1, 0; # RESULT: «<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 Perl 6:
(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 = 5; my = 2; my = 'net';sprintf "<%*.*s>", , , ; # RESULT: «< ne>»
uses $a
for the width, $b
for the precision, and $c
as the value to format; while:
NYI sprintf '<%*1$.*s>', , ;
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 $
may need escaping:
sprintf "%2\$d %d\n", 12, 34; # RESULT: «34 12»sprintf "%2\$d %d %d\n", 12, 34; # RESULT: «34 12 34»sprintf "%3\$d %d %d\n", 12, 34, 56; # RESULT: «56 12 34»NYI sprintf "%2\$*3\$d %d\n", 12, 34, 3; # " 34 12\n"NYI sprintf "%*1\$.*f\n", 4, 5, 10; # "5.0000\n"
Other examples:
NYI sprintf "%ld a big number", 4294967295;NYI sprintf "%%lld a bigger number", 4294967296;sprintf('%c', 97); # RESULT: «a»sprintf("%.2f", 1.969); # RESULT: «1.97»sprintf("%+.3f", 3.141592); # RESULT: «+3.142»sprintf('%2$d %1$d', 12, 34); # RESULT: «34 12»sprintf("%x", 255); # RESULT: «ff»
Special case: sprintf("<b>%s</b>\n", "Perl 6")
will not work, but one of the following will:
sprintf Q:b "<b>%s</b>\n", "Perl 6"; # RESULT: «<b>Perl 6</b>»sprintf "<b>\%s</b>\n", "Perl 6"; # RESULT: «<b>Perl 6</b>»sprintf "<b>%s\</b>\n", "Perl 6"; # RESULT: «<b>Perl 6</b>»
sub flat
Defined as:
multi flat(**)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
Defined as:
multi sub 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()) # 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 = %(a => 42), %(b => 13), %(a => 42);say .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
Defined as:
multi sub 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()); # OUTPUT: «(A b b C)»my = %(a => 42), %(b => 13), %(a => 42);say .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
Defined as:
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 Strsay [42, "42"].squish(with => :<eq>); # OUTPUT: «(42)»# The resulting item is Int
sub emit
Defined as
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.tap( -> );
See also the page for emit
methods.
sub undefine
Defined as:
multi sub undefine(Mu \x)multi sub undefine(Array \x)multi sub 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.
Control routines
Routines that change the flow of the program, maybe returning a value.
sub exit
Defined as:
multi sub exit()multi sub exit(Int(Any) )
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.
sub done
Defined as
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.tap( -> , done => );# OUTPUT: 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.