Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
1128 lines (818 sloc) 38.9 KB
=begin pod
=TITLE Independent routines
=SUBTITLE Routines not defined within any class or role.
These routines are defined in different files together with a class, but are not
actually attached to any particular class or role.
=head2 routine EVAL
Defined as:
=begin code :method
proto sub EVAL($code where Blob|Cool|Callable, Str() :$lang = 'perl6',
PseudoStash :$context, *%n)
=end code
=begin code :method
multi sub EVAL($code, Str :$lang where { ($lang // '') eq 'Perl5' },
PseudoStash :$context)
=end code
This routine coerces L<Cool|/type/Cool> C<$code> to L<Str|/type/Str>. If
C<$code> is a L<Blob|/type/Blob>, it'll be processed using the same encoding as
the C<$lang> compiler would: for C<perl6> C<$lang>, uses C<utf-8>; for C<Perl5>,
processes using the same rules as C<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;
# any of the above allows:
EVAL "say { 5 + 5 }"; # OUTPUT: «10␤»
In case the C<MONKEY-SEE-NO-EVAL> pragma is not activated, the compiler will
complain with a C<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 C<MONKEY-SEE-NO-EVAL> pragma.
Please note that you can interpolate to create routine names using
quotation, as can be seen in
L<this example|/language/quoting#index-entry-%26_(interpolation)>
or
L<other ways to interpolate to create identifier names|/language/syntax#Identifiers>.
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 C<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 C<EVAL> can never introduce symbols into the surrounding
scope.
=for code :skip-test<compile time error>
EVAL 'my $lives = 9'; say $lives; # error, $lives not declared
Furthermore, the C<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 C<EVAL> statement evaluates to the result of the last statement:
=begin code
sub infix:<mean>(*@a) is assoc<list> {
@a.sum / @a.elems
}
say EVAL 'say 1; 2 mean 6 mean 4'; # OUTPUT: «1␤4␤»
=end code
C<EVAL> is also a gateway for executing code in other languages:
=for code
EVAL "use v5.20; say 'Hello from perl5!'", :lang<Perl5>;
You need to have L<C<Inline::Perl5>|https://github.com/niner/Inline-Perl5> for
this to work correctly.
=head2 sub EVALFILE
Defined as:
sub EVALFILE($filename where Blob|Cool, :$lang = 'perl6')
Slurps the specified file and evaluates it. Behaves the same way as
C<EVAL> with regard to L<Blob|/type/Blob> decoding, scoping, and the C<$lang>
parameter. Evaluates to the value produced by the final statement in the
file.
=for code
EVALFILE "foo.p6";
=head2 sub mkdir
Defined as:
sub mkdir(IO() $path, Int() $mode = 0o777 --> IO::Path:D)
Creates a new directory; see L«C<mode>|/routine/mode» for explanation and
valid values for C<$mode>. Returns the L<IO::Path> object pointing to
the newly created directory on success;
L<fails|/routine/fail> with L<X::IO::Mkdir> if directory cannot be created.
Also creates parent directories, as needed (similar to *nix utility
C<mkdir> with C<-p> option); that is, C<mkdir "foo/bar/ber/meow"> will
create C<foo>, C<foo/bar>, and C<foo/bar/ber> directories if they do not
exist, as well as C<foo/bar/ber/meow>.
=head2 sub chdir
Defined as:
sub chdir(IO() $path, :$d = True, :$r, :$w, :$x --> IO::Path:D)
Changes value of C<$*CWD> variable to the provided C<$path>, optionally ensuring
the new path passes several file tests. B<NOTE:> that this routine does I<NOT>
alter the process's current directory (see
L«C<&*chdir>|/routine/&*chdir»).
Returns L«C<IO::Path>|/type/IO::Path»
representing new C<$*CWD> on success. On failure, returns
L«C<Failure>|/type/Failure» and leaves C<$*CWD> untouched.
The C<$path> can be any object with an IO method that returns an
L«C<IO::Path>|/type/IO::Path» object. The available file tests are:
=item C<:d> — check L«C<.d>|/routine/d» returns C<True>
=item C<:r> — check L«C<.r>|/routine/r» returns C<True>
=item C<:w> — check L«C<.w>|/routine/w» returns C<True>
=item C<:x> — check L«C<.x>|/routine/x» returns C<True>
By default, only C<:d> test is performed.
=for code
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:
=for code
# WRONG! DO NOT DO THIS!
my $*CWD = chdir '/tmp/';
Use L«C<indir>|/routine/indir» instead.
=head2 sub &*chdir
Defined as:
=for code
PROCESS::<&chdir> = sub (IO() $path --> IO::Path:D) { }
Changes value of C<$*CWD> variable to the provided C<$path> and sets
the process's current directory to the value of
L«C<$path.absolute>|/routine/absolute». B<NOTE:> that in most cases,
you want to use L«C<chdir>|/routine/chdir» routine instead.
Returns an L«C<IO::Path>|/type/IO::Path»
representing the new C<$*CWD> on success. On failure, returns
L«C<Failure>|/type/Failure» and leaves C<$*CWD> untouched.
The C<$path> can be any object with an IO method that returns an
L«C<IO::Path>|/type/IO::Path» object.
Note that unlike regular L«C<chdir>|/routine/chdir», there are no arguments
to specify which file tests to perform.
=for code
&*chdir('/tmp'); # change $*CWD and process's current directory to '/tmp'
&*chdir('/not-there'); # returns Failure
Note that the following construct is a mistake:
=for code
# WRONG! DO NOT DO THIS!
my $*CWD = &*chdir('/tmp');
Use the following, instead; or see L«C<indir>|/routine/indir» if
you do not need to change process's current directory:
=for code
temp $*CWD;
&*chdir('/tmp');
=head2 sub chmod
Defined as:
sub chmod(Int() $mode, *@filenames --> List)
Coerces all C<@filenames> to L«C<IO::Path>|/type/IO::Path» and calls
L«C<IO::Path.chmod>|/type/IO::Path#method_chmod» with C<$mode> on them.
Returns a L«C<List>|/type/List» containing a subset of C<@filenames> for which
C<chmod> was successfully executed.
chmod 0o755, <myfile1 myfile2>; # make two files executable by the owner
=head2 sub indir
Defined as:
sub indir(IO() $path, &code, :$d = True, :$r, :$w, :$x --> Mu)
Takes L«C<Callable>|/type/Callable» C<&code> and executes it after locally (to
C<&code>) changing C<$*CWD> variable to an L<IO::Path> object based on C<$path>,
optionally ensuring the new path passes several file tests. If C<$path> is
relative, it will be turned into an absolute path, even if an L<IO::Path>
object was given. B<NOTE:> that this routine does I<NOT> alter the process's
current directory (see L«C<&*chdir>|/routine/&*chdir»). The C<$*CWD>
outside of the C<&code> is not affected, even if C<&code> explicitly assigns
a new value to C<$*CWD>.
Returns the return value of C<&code> on success. On failure to
successfully change C<$*CWD>, returns L«C<Failure>|/type/Failure».
B<WARNING:> keep in mind that lazily evaluated things might end up NOT
having the C<$*CWD> set by C<indir> in their dynamic scope by the time
they're actually evaluated. Either ensure the generators have their
C<$*CWD> set or L<eagerly evaluate|/routine/eager> them before returning
the results from C<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 C<$path> argument can be any object with an IO method that
returns an L«C<IO::Path>|/type/IO::Path» object. The available file
tests are:
=item C<:d> — check L«C<.d>|/routine/d» returns C<True>
=item C<:r> — check L«C<.r>|/routine/d» returns C<True>
=item C<:w> — check L«C<.w>|/routine/d» returns C<True>
=item C<:x> — check L«C<.x>|/routine/d» returns C<True>
By default, only C<: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
=head2 sub print
Defined as:
multi sub print(**@args --> True)
multi sub print(Junction:D --> True)
Prints the given text on standard output (the
L«C<$*OUT>|/language/variables#index-entry-%24%2AOUT» filehandle), coercing non-L<Str|/type/Str> objects
to L<Str|/type/Str> by calling L«C<.Str> method|/routine/Str». L<Junction|/type/Junction> arguments
L<autothread|/language/glossary#index-entry-Autothreading> 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
L«C<put>|/type/independent-routines#sub_put».
=head2 sub put
Defined as:
multi sub put(**@args --> True)
multi sub put(Junction:D --> True)
Same as L«C<print>|/type/independent-routines#sub_print», except it uses
L«C<print-nl>|/routine/print-nl» (which prints a L<newline|/language/newline>,
by default) at the end. L<Junction|/type/Junction> arguments
L<autothread|/language/glossary#index-entry-Autothreading> 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␤»
=head2 sub say
Defined as:
multi sub say(**@args --> True)
Prints the "gist" of given objects. Same as L«C<put>|/type/independent-routines#sub_put»,
except uses L«C<.gist>|/routine/gist» method to obtain string
representation of the object.
B<NOTE:> the L«C<.gist>|/routine/gist» method of some objects, such as
L<Lists|/type/List#method_gist>, returns only B<partial> information
about the object (hence the "gist"). If you mean to print textual
information, you most likely want to use L«C<put>|/type/independent-routines#sub_put»
instead.
say Range; # OUTPUT: «(Range)␤»
say class Foo {}; # OUTPUT: «(Foo)␤»
say 'I ♥ Perl6'; # OUTPUT: «I ♥ Perl6␤»
say 1..Inf; # OUTPUT: «1..Inf␤»
=head2 routine note
Defined as:
method note(Mu: -->Bool:D)
multi sub note( --> Bool:D)
multi sub note(Str:D $note --> Bool:D)
multi sub note(**@args --> Bool:D)
Like L«C<say>|/routine/say», except prints output to L«C<$*ERR>|/language/variables#index-entry-%24%2AERR» handle (STDERR).
If no arguments are given to subroutine forms, will use string C<"Noted">.
=begin code
note; # STDERR OUTPUT: «Noted␤»
note 'foo'; # STDERR OUTPUT: «foo␤»
note 1..*; # STDERR OUTPUT: «1..Inf␤»
=end code
=head2 sub prompt
multi sub prompt()
multi sub prompt($msg)
L<Prints|/routine/print> C<$msg> to C<$*OUT> handle if C<$msg> was provided,
then L<gets|/routine/get> a line of input from C<$*IN> handle. By default, this
is equivalent to printing C<$msg> to
L<STDOUT|https://en.wikipedia.org/wiki/Standard_streams#Standard_output_.28stdout.29>,
reading a line from
L<STDIN|https://en.wikipedia.org/wiki/Standard_streams#Standard_input_.28stdin.29>,
removing the trailing new line, and returning the resultant string. As of Rakudo
2018.08, C<prompt> will create L<allomorphs|/language/numerics#Allomorphs> for
numeric values, equivalent to calling C<val prompt>.
=for code
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, C<$age> will be duck-typed to the allomorph L<IntStr|/type/IntStr> if it's
entered correctly as a number.
=head2 sub open
multi sub open(IO() $path, |args --> IO::Handle:D)
Creates L<a handle|/type/IO::Handle> with the given C<$path>, and calls
L«C<IO::Handle.open>|/type/IO::Handle#method_open», passing any of the
remaining arguments to it. Note that L<IO::Path> type provides numerous
methods for reading and writing from files, so in many common cases you
do not need to C<open> files or deal with L<IO::Handle> type directly.
=begin code
my $fh = open :w, '/tmp/some-file.txt';
$fh.say: 'I ♥ writing Perl 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 ♥ Perl␤»
=end code
=head2 sub slurp
Defined as:
multi sub slurp(IO::Handle:D $fh = $*ARGFILES, |c)
multi sub slurp(IO() $path, |c)
Slurps the contents of the entire file into a C<Str> (or C<Buf> if
C<:bin>). Accepts C<:bin> and C<:enc> optional named parameters, with
the same meaning as L<open()|/routine/open>; possible encodings are the
same as in all the other C<IO> methods and are listed in
L<C<encoding>|/type/IO::Handle#method_encoding> routine. The routine
will C<fail> if the file does not exist, or is a directory. Without any
arguments, sub C<slurp> operates on C<$*ARGFILES>, which defaults to
C<$*IN> in the absence of any filenames.
=begin code
# 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;
=end code
=head2 sub spurt
Defined as:
multi spurt(IO() $path, |c)
The C<$path> can be any object with an IO method that returns an
L«C<IO::Path>|/type/IO::Path» object. Calls L«C<IO::Path.spurt>|/routine/spurt»
on the C<$path>, forwarding any of the remaining arguments.
=head3 Options
=item :enc
The encoding with which the contents will be written.
=item :append
Boolean indicating whether to append to a (potentially) existing file. If
the file did not exist yet, it will be created. Defaults to C<False>.
=item :createonly
Boolean indicating whether to fail if the file already exists. Defaults to
C<False>.
=head3 Examples
=begin code
# 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 …»
=end code
=head2 sub run
Defined as:
=for code :method
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
--> Proc:D)
Runs an external command I<without involving a shell> and returns a
L<Proc|/type/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.txt
run <<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 C«< >», but try
to avoid using C<« »> as it will do word splitting if you forget to
quote variables:
=begin code
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`
=end code
Note that C<--> is required for many programs to disambiguate between
command-line arguments and
L<filenames that begin with hyphens|https://mywiki.wooledge.org/BashPitfalls#Filenames_with_leading_dashes>.
A sunk L<Proc|/type/Proc> object for a process that L<exited|/routine/exitcode>
unsuccessfully will throw. If you wish to ignore such failures, simply use
L<run|/routine/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 C<:out> or C<:err> arguments
respectively, which will make them available using the
L<C<Proc.out>|/type/Proc> method:
my $proc = run 'echo', 'Perl 6 is Great!', :out, :err;
$proc.out.slurp(:close).say; # OUTPUT: «Perl 6 is Great!␤»
$proc.err.slurp(:close).say; # OUTPUT: «␤»
You can use these arguments to redirect them to a filehandle, thus
creating a kind of I<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 L<Proc|/type/Proc> and
L<Proc::Async|/type/Proc::Async> for more details.
See also L<C<new>|/type/Proc#method_new> for more examples.
=head2 sub shell
=begin code
multi sub shell($cmd, :$in = '-', :$out = '-', :$err = '-',
Bool :$bin, Bool :$chomp = True, Bool :$merge,
Str :$enc, Str:D :$nl = "\n", :$cwd = $*CWD, :$env)
=end code
Runs a command through the system shell, which defaults to
C<%*ENV<ComSpec> /c> in Windows, C</bin/sh -c> otherwise. All shell meta
characters 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
L<run|/type/Proc#sub_run> if you want to be safe.
The return value is of L<type Proc|/type/Proc>.
shell 'ls -lR | gzip -9 > ls-lR.gz';
See L<Proc|/type/Proc#method_shell> for more details, for example on how to
capture output.
=head2 routine unpolar
Defined as:
method unpolar(Real $angle)
multi sub unpolar(Real $mag, Real $angle)
Returns a C<Complex> with the coordinates corresponding to the angle in
radians and magnitude corresponding to the object value or C<$mag> in
the case it's being used as a C<sub>
say 1.unpolar(⅓*pi);
# OUTPUT: «0.5000000000000001+0.8660254037844386i␤»
=head2 routine printf
Defined as:
method printf (*@args)
multi sub printf(Cool:D $format, *@args)
As a method, takes the object as a format using
L<the same language as C<Str.sprintf>|/type/Str#routine_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»
=head2 routine sprintf
Defined as:
method sprintf(*@args)
multi sub sprintf(Cool:D $format, *@args)
Formats and outputs a string, following
L<the same language as C<Str.sprintf>|/type/Str#routine_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 C<sprintf> and C<printf>
functions. The only difference between the two functions is that C<sprintf>
returns a string while the C<printf> function writes to a filehandle. C<sprintf>
returns a C<Str>, not a literal.
The C<$format> is scanned for C<%> characters. Any C<%> introduces a format
token. Directives guide the use (if any) of the arguments. When a directive
other than C<%> is used, it indicates how the next argument passed is to be
formatted into the string to be created.
N<The information below is for a fully functioning C<sprintf> implementation
which hasn't been achieved yet. Formats or features not yet implemented are
marked NYI.>
The directives are:
=begin table
% | 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
=end table
Compatibility:
=begin table
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
=end table
Modifiers change the meaning of format directives, but are largely
no-ops (the semantics are still being determined).
=begin table
| 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)
=end table
Between the C<%> and the format letter, you may specify several
additional attributes controlling the interpretation of the format. In
order, these are:
=head3 Format parameter index
An explicit format parameter index, such as C<2$>. By default,
C<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␤»
=head3 Flags
One or more of:
=begin table
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"
=end table
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 C<#> flag and a precision are given in the C<%o> conversion, the
necessary number of 0s is added at the beginning. If the value of the number is
C<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>␤»
=head3 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, C<'.'>, by default). This can be useful for
displaying ordinal values of characters in arbitrary strings:
=begin code :skip-test<not yet implemented>
NYI sprintf "%vd", "AB\x[100]"; # "65.66.256"
=end code
You can also explicitly specify the argument number to use for the
join string using something like C<*2$v>; for example:
=begin code :skip-test<not yet implemented>
NYI sprintf '%*4$vX %*4$vX %*4$vX', # 3 IPv6 addresses
@addr[1..3], ":";
=end code
=head3 (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 C<*> ) or
from a specified argument (e.g., with C<*2$>):
=begin code :skip-test<partly not yet implemented>
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)
=end code
If a field width obtained through C<*> is negative, it has the same
effect as the C<-> flag: left-justification.
=head3 Precision, or maximum width
You can specify a precision (for numeric conversions) or a maximum
width (for string conversions) by specifying a C<.> followed by a
number. For floating-point formats, except C<g> and C<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; # 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 C<0> flag is ignored:
(Note that this feature currently works for unsigned integer conversions, but
not for signed integer.)
=begin code :skip-test<partly not yet implemented>
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>␤»
=end code
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 C<.*>, or
from a specified argument (e.g., with C<.*2$>):
=begin code :skip-test<partly not yet implemented>
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>"
=end code
If a precision obtained through C<*> 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>␤»
=head3 Size
For numeric conversions, you can specify the size to interpret the
number as using C<l>, C<h>, C<V>, C<q>, C<L>, or C<ll>. For integer
conversions (C<d> C<u> C<o> C<x> C<X> C<b> C<i> C<D> C<U> C<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.)
=begin table
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"
=end table
=head3 Order of arguments
Normally, C<sprintf> takes the next unused argument as the value to
format for each format specification. If the format specification uses
C<*> 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; # RESULT: «< ne>␤»
uses C<$a> for the width, C<$b> for the precision, and C<$c> as the value to
format; while:
=for code :skip-test<not yet implemented>
NYI sprintf '<%*1$.*s>', $a, $b;
would use C<$a> for the width and precision and C<$b> as the value to format.
Here are some more examples; be aware that when using an explicit
index, the C<$> may need escaping:
=for code :skip-test<partly not yet implemented>
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:
=for code :skip-test<partly not yet implemented>
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: C«sprintf("<b>%s</b>\n", "Perl 6")» will not work, but
one of the following will:
=for code
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>␤␤»
=head2 sub flat
Defined as:
multi flat(**@list)
multi flat(Iterable \a)
Constructs a list which contains any arguments provided, and returns the result
of calling the C<.flat> method (L<inherited from C<Any>|/type/Any#method_flat>)
on that list or C<Iterable>:
say flat 1, (2, (3, 4), $(5, 6)); # OUTPUT: «(1 2 3 4 (5 6))␤»
=head2 routine unique
Defined as:
multi sub unique(+values, |c)
Returns a sequence of B<unique> values from the invocant/argument list, such
that only the first occurrence of each duplicated value remains in the
result list. C<unique> uses the semantics of the L<===> operator to decide
whether two objects are the same, unless the optional C<: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 L<C<squish>> instead if you know the input is sorted such that identical
objects are adjacent.)
The optional C<: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 C<:with> parameter. For
instance if one wants a list of unique hashes, one could use the C<eqv>
comparator.
Example:
my @list = %(a => 42), %(b => 13), %(a => 42);
say @list.unique(:with(&[eqv])) # OUTPUT: «({a => 42} {b => 13})␤»
B<Note:> since C<:with> L<Callable|/type/Callable> has to be tried with all the
items in the list, this makes C<unique> follow a path with much higher
algorithmic complexity. You should try to use the C<:as> argument instead,
whenever possible.
=head2 routine repeated
Defined as:
multi sub repeated(+values, |c)
This returns a sequence of B<repeated> values from the invocant/argument list.
It takes the same parameters as L<C<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 L<C<unique>|/type/Any#method_unique> the associative argument
C<:as> takes a Callable that normalizes the element before comparison, and
C<:with> takes a the equality comparison function that is going to be used.
=head2 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 L<C<unique>>,
C<squish> uses the semantics of the L<===> operator to decide whether two
objects are the same. Unlike L<C<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 C<:as> parameter, just like with L<C<unique>>, allows values to be
temporarily transformed before comparison.
The optional C<: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
=head2 sub emit
Defined as
sub emit(\value --> Nil)
If used outside any supply or react block, throws an exception C<emit without
supply or react>. Within a L<Supply|/type/Supply> block, it will add a message to the stream.
=begin code
my $supply = supply {
for 1 .. 10 {
emit($_);
}
}
$supply.tap( -> $v { say "First : $v" });
=end code
See also L<the page for C<emit> methods|/routine/emit>.
=head2 sub undefine
Defined as:
multi sub undefine(Mu \x)
multi sub undefine(Array \x)
multi sub undefine(Hash \x)
B<DEPRECATED> in 6.d language version and will be removed in 6.e. For
L<Array|/type/Array> and L<Hash|/type/Hash>, it will become equivalent to
assigning L<Empty|/type/Slip#index-entry-Empty-Empty>; for everything else,
equivalent to assigning L<Nil|/type/Nil> or C<Empty> in the case of arrays or
hashes, whose use is advised.
=head1 Control routines
Routines that change the flow of the program, maybe returning a value.
=head2 sub exit
Defined as:
multi sub exit()
multi sub exit(Int(Any) $status)
Exits the current process with return code C<$status> or zero if no
value has been specified. The exit value (C<$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 L<Main|/routine/MAIN>.
C<exit> prevents the L<LEAVE|/language/phasers#LEAVE> phaser to be
executed, but it will run the code in the
L<C<&*EXIT>|/language/variables#index-entry-%24*EXIT> variable.
C<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 L<exceptions|/language/exceptions>
instead.
=head2 sub done
Defined as
sub done(--> Nil)
If used outside any supply or react block, throws an exception C<done without
supply or react>. Within a L<Supply|/type/Supply> block, it will indicate the
supply will no longer emit anything. See also L<documentation on method
C<done>|/routine/done>.
=for code
my $supply = supply {
for 1 .. 3 {
emit($_);
}
done;
}
$supply.tap( -> $v { say "Second : $v" }, done => { say "No more" });
# OUTPUT: OUTPUT: «Second : 1␤Second : 2␤Second : 3␤No More␤»
The block passed to the C<done> named argument will be run when C<done> is
called within the C<supply> block.
=end pod
# vim: expandtab softtabstop=4 shiftwidth=4 ft=perl6
You can’t perform that action at this time.