-
Notifications
You must be signed in to change notification settings - Fork 293
/
5to6-nutshell.pod6
1802 lines (1323 loc) · 55.5 KB
/
5to6-nutshell.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
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
=begin pod :tag<convert>
=TITLE Perl 5 to Perl 6 guide - Overview
=SUBTITLE How do I do what I used to do? (Perl 6 in a nutshell.)
This page attempts to index the changes in syntax and semantics from
Perl 5 to Perl 6. Whatever worked in Perl 5 and must be written differently
in Perl 6, should be listed here (whereas many I<new> Perl 6 features and
idioms won't be).
Hence this should not be mistaken for a beginner tutorial or a promotional
overview of Perl 6; it is intended as a technical reference for Perl 6
learners with a strong Perl 5 background and for anyone porting Perl 5 code
to Perl 6 (though note that L<#Automated Translation> might be more
convenient).
A note on semantics; when we say "now" in this document, we mostly just
mean "now that you are trying out Perl 6." We don't mean to imply that
Perl 5 is now suddenly obsolete. Quite the contrary, most of us love
Perl 5, and we expect Perl 5 to continue in use for a good many years.
Indeed, one of our more important goals has been to make interaction between
Perl 5 and Perl 6 run smoothly. However, we do also like the design
decisions in Perl 6, which are certainly newer and arguably better
integrated than many of the historical design decisions in Perl 5.
So many of us do hope that over the next decade or two, Perl 6 will
become the more dominant language. If you want to take "now" in that
future sense, that's okay too. But we're not at all interested in the
either/or thinking that leads to fights.
=head1 CPAN
See L<https://modules.perl6.org/> .
If the module that you were using has not been converted to Perl 6, and no
alternative is listed in this document, then its use under Perl 6 may not
have been addressed yet.
The L<Inline::Perl5|https://github.com/niner/Inline-Perl5/> project makes
it possible to C<use> Perl 5 modules directly from Perl 6 code by using
an embedded instance of the C<perl> interpreter to run Perl 5 code.
This is as simple as:
=for code :skip-test<Inline module not always present when testing>
# the :from<Perl5> makes Perl 6 load Inline::Perl5 first (if installed)
# and then load the Scalar::Util module from Perl 5
use Scalar::Util:from<Perl5> <looks_like_number>;
say looks_like_number "foo"; # 0
say looks_like_number "42"; # 1
A number of Perl 5 modules have been ported to Perl 6, trying to maintain
the API of these modules as much as possible, as part of the CPAN Butterfly
Plan. These can be found at L<https://modules.perl6.org/t/CPAN5>.
=head1 Syntax
=head2 Identifiers
In identifiers, Perl 6 allows the use of dashes (C<->), underscores (C<_>), apostrophes (C<'>), and alphanumerics:
sub test-doesn't-hang { ... }
my $ความสงบ = 42;
my \Δ = 72; say 72 - Δ;
=head2 C«->» Method calls
If you've read any Perl 6 code at all, it's immediately obvious that
method call syntax now uses a dot instead of an arrow:
=for code :lang<perl5>
$person->name # Perl 5
=for code :preamble<no strict;>
$person.name # Perl 6
The dot notation is both easier to type and more of an industry standard.
But we also wanted to steal the arrow for something else. (Concatenation
is now done with the C<~> operator, if you were wondering.)
To call a method whose name is not known until runtime:
=for code :lang<perl5>
$object->$methodname(@args); # Perl 5
=for code :preamble<no strict;>
$object."$methodname"(@args); # Perl 6
If you leave out the quotes, then Perl 6 expects C<$methodname> to contain
a C<Method> object, rather than the simple string name of the method. Yes,
B<everything> in Perl 6 can be considered an object.
=head2 Whitespace
Perl 5 allows a surprising amount of flexibility in the use of whitespace,
even with strict mode and warnings turned on:
=for code :lang<perl5>
# unidiomatic but valid Perl 5
say"Hello ".ucfirst ($people
[$ i]
->
name)."!"if$greeted[$i]<1;
Perl 6 also endorses programmer freedom and creativity, but balanced
syntactic flexibility against its design goal of having a consistent,
deterministic, extensible grammar that supports single-pass parsing and
helpful error messages, integrates features like custom operators cleanly,
and doesn't lead programmers to accidentally misstate their intent.
Also, the practice of "code golf" is slightly de-emphasized; Perl 6 is
designed to be more concise in concepts than in keystrokes.
As a result, there are various places in the syntax where whitespace is
optional in Perl 5, but is either mandatory or forbidden in Perl 6. Many of
those restrictions are unlikely to concern much real-life Perl code (e.g.,
whitespace being disallowed between the sigil and name of a variable), but
there are a few that will unfortunately conflict with some Perl hackers'
habitual coding styles:
=begin item
I<No space allowed before the opening parenthesis of an argument list.>
=for code :lang<perl5>
substr ($s, 4, 1); # Perl 5 (in Perl 6 this would try to pass a single
# argument of type List to substr)
=for code :preamble<no strict;>
substr($s, 4, 1); # Perl 6
substr $s, 4, 1; # Perl 6 - alternative parentheses-less style
Should this really be a problem for you, then you might want to have a look
at the C<Slang::Tuxic> module in the Perl 6 ecosystem: it changes the grammar
of Perl 6 in such a way that you B<can> have a space before the opening
parenthesis of an argument list.
=end item
=begin item
I<Space is B<required> immediately after keywords>
=for code :lang<perl5>
my($alpha, $beta); # Perl 5, tries to call my() sub in Perl 6
=for code :preamble<no strict;>
my ($alpha, $beta); # Perl 6
=for code :lang<perl5>
if($a < 0) { ... } # Perl 5, dies in Perl 6
=for code :preamble<no strict;>
if ($a < 0) { ... } # Perl 6
if $a < 0 { ... } # Perl 6, more idiomatic
=for code :lang<perl5>
while($x-- > 5) { ... } # Perl 5, dies in Perl 6
=for code :preamble<no strict;>
while ($x-- > 5) { ... } # Perl 6
while $x-- > 5 { ... } # Perl 6, more idiomatic
=end item
=begin item
I<No space allowed after a prefix operator, or before a
postfix/postcircumfix operator (including array/hash subscripts).>
=for code :lang<perl5>
$seen {$_} ++; # Perl 5
=for code :preamble<no strict;>
%seen{$_}++; # Perl 6
=end item
=begin item
I<Space required before an infix operator if it would
conflict with an existing postfix/postcircumfix operator.>
=for code :lang<perl5>
$n<1; # Perl 5 (in Perl 6 this would conflict with postcircumfix < >)
=for code :preamble<no strict;>
$n < 1; # Perl 6
=end item
=begin item
I<However, whitespace B<is allowed> before the period of a method call!>
=for code :lang<perl5>
# Perl 5
my @books = $xml
->parse_file($file) # some comment
->findnodes("/library/book");
=for code :preamble<no strict;>
# Perl 6
my @books = $xml
.parse-file($file) # some comment
.findnodes("/library/book");
=end item
However, note that you can use L<unspace|https://design.perl6.org/S02.html#Unspaces>
to add whitespace in Perl 6 code in places where it is otherwise not
allowed.
See also L<S03#Minimal whitespace DWIMmery|https://design.perl6.org/S03.html#Minimal_whitespace_DWIMmery> and
L<S04#Statement parsing|https://design.perl6.org/S04.html#Statement_parsing>
in the Perl 6 design docs.
=head2 Sigils
In Perl 5, arrays and hashes use changing sigils depending on how they are
being accessed. In Perl 6 the sigils are invariant, no matter how the
variable is being used - you can think of them as part of the variable's
name.
=head3 C<$> Scalar
The C<$> sigil is now always used with "scalar" variables (e.g. C<$name>),
and no longer for L<array indexing|#[]_Array_indexing/slicing> and L<Hash
indexing|#{}_Hash_indexing/slicing>. That is, you can still use C<$x[1]>
and C<$x{"foo"}>, but it will act on $x, with no effect on a similarly
named @x or %x. Those would now be accessed with @x[1] and %x{"foo"}.
=head3 C<@> Array
The C<@> sigil is now always used with "array" variables (e.g. C<@months>,
C<@months[2]>, C<@months[2, 4]>), and no longer for L<value-slicing
hashes|#{}_Hash_indexing/slicing>.
=head3 C<%> Hash
The C<%> sigil is now always used with "hash" variables (e.g. C<%calories>,
C<%calories<apple>>, C<%calories<pear plum>>), and no longer for
L<key/value-slicing arrays|#[]_Array_indexing/slicing>.
=head3 C<&> Sub
The C<&> sigil is now used consistently (and without the help of a
backslash) to refer to the function object of a named subroutine/operator
without invoking it, i.e. to use the name as a "noun" instead of a "verb":
=for code :lang<perl5>
my $sub = \&foo; # Perl 5
=for code :preamble<sub foo {};>
my $sub = &foo; # Perl 6
=for code :lang<perl5>
callback => sub { say @_ } # Perl 5 - can't pass built-in sub directly
=for code
callback => &say # Perl 6 - & gives "noun" form of any sub
Since Perl 6 does not allow adding/removing symbols in a lexical scope once
it has finished compiling, there is no equivalent to Perl 5's
C<undef &foo;>, and the closest equivalent to Perl 5's C<defined &foo>
would be C<defined ::('&foo')> (which uses the "dynamic symbol lookup"
syntax). However, you can declare a mutable named subroutine with
C<my &foo;> and then change its meaning at runtime by assigning to C<&foo>.
In Perl 5, the ampersand sigil can additionally be used to call subroutines
in special ways with subtly different behavior compared to normal sub
calls. In Perl 6 those special forms are no longer available:
=begin item
C<&foo(...)> I<for circumventing a function prototype>
In Perl 6 there are no prototypes, and it no longer
makes a difference whether you, say, pass a literal code block or a
variable holding a code object as an argument:
=for code :lang<perl5>
# Perl 5:
first_index { $_ > 5 } @values;
&first_index($coderef, @values); # (disabling the prototype that parses a
# literal block as the first argument)
=for code
# Perl 6:
first { $_ > 5 }, @values, :k; # the :k makes first return an index
first $coderef, @values, :k;
=end item
=begin item
C<&foo;> I<and> C<goto &foo;> I<for re-using the caller's argument list /
replacing the caller in the call stack>. Perl 6 can use either L<C<callsame>|/language/functions#index-entry-dispatch_callsame> for re-dispatching or L<C<nextsame>|/language/functions#index-entry-dispatch_nextsame> and L<C<nextwith>|/language/functions#index-entry-dispatch_nextwith>, which have no exact equivalent in Perl 5.
=begin comment
# TODO: Suggest .nextsame and .nextwith once they've been implemented in Rakudo.
=end comment
=for code :lang<perl5>
sub foo { say "before"; &bar; say "after" } # Perl 5
=for code
sub foo { say "before"; bar(|@_); say "after" } # Perl 6 - have to be explicit
=for code :lang<perl5>
sub foo { say "before"; goto &bar } # Perl 5
=begin code
proto foo (|) {*};
multi foo ( Any $n ) {
say "Any"; say $n;
};
multi foo ( Int $n ) {
say "Int"; callsame;
};
foo(3); # /language/functions#index-entry-dispatch_callsame
=end code
=end item
=head3 C<*> Glob
=comment TODO: Research what exact use-cases still need typeglobs in Perl 5
today, and refactor this section to list them (with translations).
In Perl 5, the C<*> sigil referred to the GLOB structure that Perl uses to
store non-lexical variables, filehandles, subs, and formats.
(This should not be confused with the Perl 5 built-in C<glob()> function,
which reads filenames from a directory).
You are most likely to encounter a GLOB in code written on a early Perl
version that does not support lexical filehandles, when a filehandle needed
to be passed into a sub.
=for code :lang<perl5>
# Perl 5 - ancient method
sub read_2 {
local (*H) = @_;
return scalar(<H>), scalar(<H>);
}
open FILE, '<', $path or die;
my ($line1, $line2) = read_2(*FILE);
You should refactor your Perl 5 code to remove the need for the GLOB,
before translating into Perl 6.
=for code :lang<perl5>
# Perl 5 - modern use of lexical filehandles
sub read_2 {
my ($fh) = @_;
return scalar(<$fh>), scalar(<$fh>);
}
open my $in_file, '<', $path or die;
my ($line1, $line2) = read_2($in_file);
And here's just one possible Perl 6 translation:
=for code :preamble<no strict;>
# Perl 6
sub read-n($fh, $n) {
return $fh.get xx $n;
}
my $in-file = open $path or die;
my ($line1, $line2) = read-n($in-file, 2);
=head2 [] Array indexing/slicing
Index and slice operations on arrays no longer inflect the variable's
L<sigil|#@_Array>, and adverbs can be used to control the type of slice:
=begin item
I<Indexing>
=for code :lang<perl5>
say $months[2]; # Perl 5
=for code :preamble<no strict;>
say @months[2]; # Perl 6 - @ instead of $
=end item
=begin item
I<Value-slicing>
=for code :preamble<no strict;>
say join ',', @months[6, 8..11]; # Perl 5 and Perl 6
=end item
=begin item
I<Key/value-slicing>
=for code :lang<perl5>
say join ',', %months[6, 8..11]; # Perl 5
=for code :preamble<no strict;>
say join ',', @months[6, 8..11]:kv; # Perl 6 - @ instead of %; use :kv adverb
=end item
Also note that the subscripting brackets are now a normal postcircumfix
operator rather than a special syntactic form, and thus L<checking for
existence of elements|#exists> and L<unsetting elements|#delete> is done
with adverbs.
=head2 {} Hash indexing/slicing
Index and slice operations on hashes no longer inflect the variable's
L<sigil|#%_Hash>, and adverbs can be used to control the type of slice.
Also, single-word subscripts are no longer magically autoquoted inside the
curly braces; instead, the new angle-brackets version is available which
always autoquotes its contents (using the same rules as the C<qw//> quoting
construct):
=begin item
I<Indexing>
=for code :lang<perl5>
say $calories{"apple"}; # Perl 5
=for code :preamble<no strict;>
say %calories{"apple"}; # Perl 6 - % instead of $
=for code :lang<perl5>
say $calories{apple}; # Perl 5
=for code :preamble<no strict;>
say %calories<apple>; # Perl 6 - angle brackets; % instead of $
say %calories«"$key"»; # Perl 6 - double angles interpolate as a list of Str
=end item
=begin item
I<Value-slicing>
=for code :lang<perl5>
say join ',', @calories{'pear', 'plum'}; # Perl 5
=for code :preamble<no strict;>
say join ',', %calories{'pear', 'plum'}; # Perl 6 - % instead of @
say join ',', %calories<pear plum>; # Perl 6 (prettier version)
my $keys = 'pear plum';
say join ',', %calories«$keys»; # Perl 6 the split is done after interpolation
=end item
=begin item
I<Key/value-slicing>
=for code :lang<perl5>
say join ',', %calories{'pear', 'plum'}; # Perl 5
=for code :preamble<no strict;>
say join ',', %calories{'pear', 'plum'}:kv; # Perl 6 - use :kv adverb
say join ',', %calories<pear plum>:kv; # Perl 6 (prettier version)
=end item
Also note that the subscripting curly braces are now a normal postcircumfix
operator rather than a special syntactic form, and thus L<checking for
existence of keys|#exists> and L<removing keys|#delete> is done with
adverbs.
=head2 Creating references and using them
In Perl 5, references to anonymous arrays and hashes and subs are returned
during their creation. References to existing named variables and subs were
generated with the C<\> operator. the "referencing/dereferencing"
metaphor does not map cleanly to the actual Perl 6 container system,
so we will have to focus on the intent of the reference operators
instead of the actual syntax.
=for code :lang<perl5>
my $aref = \@aaa ; # Perl 5
This might be used for passing a reference to a routine, for instance. But in Perl 6, the default behavior is a pass by reference.
=begin code
my @a = 4,8,15;
(-> @array { @array[0] = 66})(@a);
say @a; # OUTPUT: «[66 8 15]»
=end code
The declared C<@a> is passed by reference, and its first value modified inside the declared routine.
In Perl 5, the syntax for dereferencing an entire reference is the
type-sigil and curly braces, with the reference inside the curly braces. In Perl 6, this concept simply does not apply, since the I<reference> metaphor does not really apply.
In Perl 5, the arrow operator, C«->» , is used for single access to a
composite's reference or to call a sub through its reference. In Perl 6,
the dot operator C<.> is always used for object methods, but the rest does not really apply.
=for code :lang<perl5>
# Perl 5
say $arrayref->[7];
say $hashref->{'fire bad'};
say $subref->($foo, $bar);
In relatively recent versions of Perl 5 (5.20 and later), a new feature allows the use of the arrow
operator for dereferencing: see
L<Postfix Dereferencing|http://search.cpan.org/~shay/perl-5.20.1/pod/perl5200delta.pod#Experimental_Postfix_Dereferencing>. This
can be used to create an array from a scalar. This operation is
usually called I<decont>, as in decontainerization, and in Perl 6
methods such as C<.list> and C<.hash> are used:
=for code :lang<perl5>
# Perl 5.20
use experimental qw< postderef >;
my @a = $arrayref->@*;
my %h = $hashref->%*;
my @slice = $arrayref->@[3..7];
=for code :preamble<no strict;>
# Perl 6
my @a = $contains-an-array.list; # or @($arrayref)
my %h = $contains-a-hash.hash; # or %($hashref)
The "Zen" slice does the same thing:
=for code :preamble<no strict;>
# Perl 6
my @a = $contains-an-array[];
my %h = $contains-a-hash{};
See L<the "Containers" section of the documentation|/language/containers> for more information.
=head1 Operators
See L<S03/Operators|https://design.perl6.org/S03.html#Overview>
for full details on all operators.
Unchanged:
=item C<+> Numeric Addition
=item C<-> Numeric Subtraction
=item C<*> Numeric Multiplication
=item C</> Numeric Division
=item C<%> Numeric Modulus
=item C<**> Numeric Exponentiation
=item C<++> Numeric Increment
=item C<--> Numeric Decrement
=item C<! && || ^> Booleans, high-precedence
=item C<not and or xor> Booleans, low-precedence
=item C«== != < > <= >=» Numeric comparisons
=item C<eq ne lt gt le ge> String comparisons
=head2 C<,> (Comma) List Separator
Unchanged, but note that in order to flatten an array variable to a list (in
order to append or prefix more items) one should use the C<|> operator
(see also L<Slip|/type/Slip>). For instance:
=for code
my @numbers = 100, 200, 300;
my @more_numbers = 500, 600, 700;
my @all_numbers = |@numbers, 400, |@more_numbers;
That way one can concatenate arrays.
Note that one does not need to have any parentheses on the right hand side:
the List Separator takes care of creating the list, B<not> the parentheses!
=head2 C«<=> cmp» Three-way comparisons
In Perl 5, these operators returned -1, 0, or 1.
In Perl 6, they return C<Order::Less>, C<Order::Same>, or C<Order::More>.
C«cmp» is now named C«leg»; it forces string context for the comparison.
C«<=>» still forces numeric context.
C«cmp» in Perl 6 does either C«<=>» or C<leg>, depending on the existing
type of its arguments.
=head2 C<~~> Smartmatch operator
While the operator has not changed, the rules for what exactly is matched
depend on the types of both arguments, and those rules are far from
identical in Perl 5 and Perl 6. See L<~~|/routine/~~> and
L<S03/Smartmatching|https://design.perl6.org/S03.html#Smart_matching>
=head2 C<& | ^> String Bitwise ops
=head2 C<& | ^> Numeric Bitwise ops
=head2 C<& | ^> Boolean ops
In Perl 5, C<& | ^> were invoked according to the contents of their
arguments. For example, C<31 | 33> returns a different result than C<"31" |
"33">.
In Perl 6, those single-character ops have been removed, and replaced by
two-character ops which coerce their arguments to the needed context.
=begin code :skip-test
# Infix ops (two arguments; one on each side of the op)
+& +| +^ And Or Xor: Numeric
~& ~| ~^ And Or Xor: String
?& ?| ?^ And Or Xor: Boolean
# Prefix ops (one argument, after the op)
+^ Not: Numeric
~^ Not: String
?^ Not: Boolean (same as the ! op)
=end code
=head2 C«<< >>» Numeric shift left|right ops
Replaced by C«+<» and C«+>» .
=for code :lang<perl5>
say 42 << 3; # Perl 5
=for code
say 42 +< 3; # Perl 6
=head2 C«=>» Fat comma
In Perl 5, C«=>» acted just like a comma, but also quoted its left-hand
side.
In Perl 6, C«=>» is the L<Pair|/type/Pair> operator, which is quite different in
principle, but works the same in many situations.
If you were using C«=>» in hash initialization, or in passing arguments to
a sub that expects a hashref, then the usage is likely identical.
sub get_the_loot { ... }; # Perl 6 stub
# Works in Perl 5 and Perl 6
my %hash = ( AAA => 1, BBB => 2 );
get_the_loot( 'diamonds', { quiet_level => 'very', quantity => 9 }); # Note the curly braces
If you were using C«=>» as a convenient shortcut to not have to quote part
of a list, or in passing arguments to a sub that expects a flat list of
KEY, VALUE, KEY, VALUE, then continuing to use C«=>» may break your code.
The easiest workaround is to change the fat comma to a regular comma, and
manually add quotes to its left-hand side. Or, you can change the sub's API
to L<slurp a hash|/type/Signature#Slurpy_(A.K.A._Variadic)_Parameters>.
A better long-term solution is to change the sub's API to
expect L<Pair|/type/Pair>s; however, this requires you to change
all sub calls at once.
=begin code :lang<perl5>
# Perl 5
sub get_the_loot {
my $loot = shift;
my %options = @_;
# ...
}
# Note: no curly braces in this sub call
get_the_loot( 'diamonds', quiet_level => 'very', quantity => 9 );
=end code
=begin code
# Perl 6, original API
sub get_the_loot( $loot, *%options ) { # The * means to slurp everything
...
}
get_the_loot( 'diamonds', quiet_level => 'very', quantity => 9 ); # Note: no curly braces in this API
# Perl 6, API changed to specify valid options
# The colon before the sigils means to expect a named variable,
# with the key having the same name as the variable.
sub get_the_loot( $loot, :$quiet_level?, :$quantity = 1 ) {
# This version will check for unexpected arguments!
...
}
get_the_loot( 'diamonds', quietlevel => 'very' ); # Throws error for misspelled parameter name
=end code
=head2 C<? :> Ternary operator
The conditional operator C<? :> has been replaced
by C<?? !!>:
=for code :lang<perl5>
my $result = $score > 60 ? 'Pass' : 'Fail'; # Perl 5
=for code :preamble<my $score>
my $result = $score > 60 ?? 'Pass' !! 'Fail'; # Perl 6
=head2 C<.> (Dot) String Concatenation
Replaced by the tilde.
Mnemonic: think of "stitching" together the two strings with needle and thread.
=for code :lang<perl5>
$food = 'grape' . 'fruit'; # Perl 5
=for code :preamble<no strict;>
$food = 'grape' ~ 'fruit'; # Perl 6
=head2 C<x> List Repetition or String Repetition operator
In Perl 5, C<x> is the Repetition operator, which behaves differently in
scalar or list contexts:
=item in scalar context C<x> repeats a string;
=item in list context C<x> repeats a list, but only if the left argument
is parenthesized!
Perl 6 uses two different Repetition operators to achieve the above:
=item C<x> for string repetitions (in any context);
=item C<xx> for list repetitions (in any context).
Mnemonic: C<x> is short and C<xx> is long, so C<xx> is the one used for lists.
=for code :lang<perl5>
# Perl 5
print '-' x 80; # Print row of dashes
@ones = (1) x 80; # A list of 80 1's
@ones = (5) x @ones; # Set all elements to 5
=for code :preamble<no strict;>
# Perl 6
print '-' x 80; # Unchanged
@ones = 1 xx 80; # Parentheses no longer needed
@ones = 5 xx @ones; # Parentheses no longer needed
=head2 C<..> C<...> Two Dots or Three Dots, Range op or Flipflop op
In Perl 5, C<..> was one of two completely different operators, depending
on context.
In list context, C<..> is the familiar range operator. Ranges from Perl 5
code should B<not> require translation.
In scalar context, C<..> and C<...> were the little-known Flipflop
operators. They have been replaced by C<ff> and C<fff>.
=head2 String interpolation
In Perl 5, C<"${foo}s"> deliminates a variable name from regular text next to it.
In Perl 6, simply extend the curly braces to include the sigil too: C<"{$foo}s">.
This is in fact a very simple case of interpolating an expression.
=head1 Compound Statements
=head2 Conditionals
=head3 C<if> C<elsif> C<else> C<unless>
Mostly unchanged; parentheses around the conditions are now optional, but if
used, must not immediately follow the keyword, or it will be taken as a function
call instead. Binding the conditional expression to a variable is also a little different:
=for code :lang<perl5>
if (my $x = dostuff()) {...} # Perl 5
=for code :preamble<sub dostuff {};>
if dostuff() -> $x {...} # Perl 6
(You can still use the C<my> form in Perl 6, but it will scope to the
outer block, not the inner.)
The C<unless> conditional only allows for a single block in Perl 6;
it does not allow for an C<elsif> or C<else> clause.
=head3 C<given>-C<when>
The C<given>-C<when> construct is like a chain of C<if>-C<elsif>-C<else>
statements or like the C<switch>-C<case> construct in e.g. C. It has the
general structure:
=for code :lang<pseudo>
given EXPR {
when EXPR { ... }
when EXPR { ... }
default { ... }
}
In its simplest form, the construct is as follows:
=for code :preamble<no strict;>
given $value { # assigns $_
when "a match" { # if $_ ~~ "a match"
# do-something();
}
when "another match" { # elsif $_ ~~ "another match"
# do-something-else();
}
default { # else
# do-default-thing();
}
}
This is simple in the sense that a scalar value is matched in the C<when>
statements against C<$_>, which was set by the C<given>. More generally,
the matches are actually smartmatches on C<$_> such that lookups using more
complex entities such as regexps can be used instead of scalar values.
See also the warnings on the smartmatch op above.
=head2 Loops
=head3 C<while> C<until>
Mostly unchanged; parentheses around the conditions are now optional, but if
used, must not immediately follow the keyword, or it will be taken as a function
call instead. Binding the conditional expression to a variable is also a little different:
=for code :lang<perl5>
while (my $x = dostuff()) {...} # Perl 5
=for code :preamble<sub dostuff {};>
while dostuff() -> $x {...} # Perl 6
(You can still use the C<my> form in Perl 6, but it will scope to the
outer block, not the inner.)
Note that reading line-by-line from a filehandle has changed.
In Perl 5, it was done in a C<while> loop using the diamond operator. Using
C<for> instead of C<while> was a common bug, because the C<for> causes the
whole file to be sucked in at once, swamping the program's memory usage.
In Perl 6, C<for> statement is B<lazy>, so we read line-by-line in a C<for>
loop using the C<.lines> method.
=for code :lang<perl5>
while (<IN_FH>) { } # Perl 5
=for code :preamble<no strict;>
for $IN_FH.lines { } # Perl 6
Also note that in Perl 6, lines are C<chomp>ed by default.
=head3 C<do> C<while>/C<until>
=begin code :lang<perl5>
# Perl 5
do {
...
} while $x < 10;
do {
...
} until $x >= 10;
=end code
The construct is still present, but C<do> was renamed to C<repeat>, to better
represent what the construct does:
=begin code :preamble<no strict;>
# Perl 6
repeat {
...
} while $x < 10;
repeat {
...
} until $x >= 10;
=end code
=head3 C<for> C<foreach>
Note first this common misunderstanding about the C<for> and C<foreach>
keywords. Many programmers think that they distinguish between the C-style
three-expression form and the list-iterator form; they do not! In fact,
the keywords are interchangeable; the Perl 5 compiler looks for the
semi-colons within the parentheses to determine which type of loop to parse.
The C-style three-factor form now uses the C<loop> keyword, and is
otherwise unchanged. The parentheses B<are> still required.
=for code :lang<perl5>
for ( my $i = 1; $i <= 10; $i++ ) { ... } # Perl 5
=for code
loop ( my $i = 1; $i <= 10; $i++ ) { ... } # Perl 6
The loop-iterator form is named C<for> in Perl 6 and C<foreach> is no longer a keyword.
The C<for> loop has the following rules:
=item parentheses are optional;
=item the iteration variable, if any, has been moved from appearing before the list, to
appearing after the list and an added arrow operator;
=item the iteration variable is now always lexical: C<my> is neither needed nor
allowed;
=item the iteration variable is a I<read-only> alias to the current list element (in Perl 5
it is a I<read-write> alias!). If a read-write alias is required, change the C«->» before the iteration
variable to a C«<->». When translating from Perl 5, inspect the use of the loop variable to decide if
read-write is needed.
=for code :lang<perl5>
for my $car (@cars) {...} # Perl 5; read-write
=for code :preamble<no strict;>
for @cars -> $car {...} # Perl 6; read-only
for @cars <-> $car {...} # Perl 6; read-write
If the default topic C<$_> is being used, it is also read-write.
=for code :lang<perl5>
for (@cars) {...} # Perl 5; $_ is read-write
=for code :preamble<no strict;>
for @cars {...} # Perl 6; $_ is read-write
for @cars <-> $_ {...} # Perl 6; $_ is also read-write
It is possible to consume more than one element of the list in each iteration simply specifying
more than one variable after the arrow operator:
=begin code
my @array = 1..10;
for @array -> $first, $second {
say "First is $first, second is $second";
}
=end code
=head4 C<each>
Here is the equivalent to Perl 5’s C<while…each(%hash)> or C<while…each(@array)>
(i.e., iterating over both the keys/indices and values of a data structure) in
Perl 6:
=for code :lang<perl5>
while (my ($i, $v) = each(@array)) { ... } # Perl 5
=for code :preamble<no strict;>
for @array.kv -> $i, $v { ... } # Perl 6
=for code :lang<perl5>
while (my ($k, $v) = each(%hash)) { ... } # Perl 5
=for code :preamble<no strict;>
for %hash.kv -> $k, $v { ... } # Perl 6
=head2 Flow Control statements
Unchanged:
=item C<next>
=item C<last>
=item C<redo>
=head3 C<continue>
There is no longer a C<continue> block.
Instead, use a C<NEXT> block (phaser) within the body of the loop.
=for code :lang<perl5>
# Perl 5
my $str = '';
for (1..5) {
next if $_ % 2 == 1;
$str .= $_;
}
continue {
$str .= ':'
}
=for code
# Perl 6
my $str = '';
for 1..5 {
next if $_ % 2 == 1;
$str ~= $_;
NEXT {
$str ~= ':'
}
}
Please note that phasers don't really need a block. This can be very handy
when you don't want another scope:
=for code
# Perl 6
my $str = '';
for 1..5 {
next if $_ % 2 == 1;
$str ~= $_;
NEXT $str ~= ':';
}
=head1 Functions
=comment NOTE FOR EDITORS: When adding functions, please place them in
alphabetical order.
=head2 Built-ins with bare blocks
Builtins that previously accepted a bare block followed, without
a comma, by the remainder of the arguments will now
require a comma between the block and the arguments e.g. C<map>, C<grep>,
etc.
=for code :lang<perl5>
my @results = grep { $_ eq "bars" } @foo; # Perl 5
=for code :preamble<no strict;>
my @results = grep { $_ eq "bars" }, @foo; # Perl 6
=head2 C<delete>
Turned into an adverb of the
L<C<{}> hash subscripting|#{}_Hash_indexing/slicing>
and L<C<[]> array subscripting|#[]_Array_indexing/slicing> operators.
=for code :lang<perl5>
my $deleted_value = delete $hash{$key}; # Perl 5
=for code :preamble<no strict;>
my $deleted_value = %hash{$key}:delete; # Perl 6 - use :delete adverb
=for code :lang<perl5>
my $deleted_value = delete $array[$i]; # Perl 5
=for code :preamble<no strict;>
my $deleted_value = @array[$i]:delete; # Perl 6 - use :delete adverb
=head2 C<exists>
Turned into an adverb of the
L<C<{}> hash subscripting|#{}_Hash_indexing/slicing>
and L<C<[]> array subscripting|#[]_Array_indexing/slicing> operators.
=for code :lang<perl5>
say "element exists" if exists $hash{$key}; # Perl 5
=for code :preamble<no strict;>
say "element exists" if %hash{$key}:exists; # Perl 6 - use :exists adverb
=for code :lang<perl5>
say "element exists" if exists $array[$i]; # Perl 5
=for code :preamble<no strict;>
say "element exists" if @array[$i]:exists; # Perl 6 - use :exists adverb
=head1 Regular Expressions ( Regex / Regexp )
=head2 Change C<=~> and C<!~> to C<~~> and C<!~~> .
In Perl 5, matches and substitutions are done against a variable using the
C<=~> regexp-binding op.
In Perl 6, the C<~~> smartmatch op is used instead.
=for code :lang<perl5>
next if $line =~ /static/ ; # Perl 5
=for code :preamble<no strict;>
next if $line ~~ /static/ ; # Perl 6