/
independent-routines.pod6
944 lines (692 loc) · 32.9 KB
/
independent-routines.pod6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
=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: «14»
=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))»
=end pod
# vim: expandtab softtabstop=4 shiftwidth=4 ft=perl6