@@ -52,7 +52,7 @@ Note that subroutine signatures allow passing around of containers:
52
52
}
53
53
my $x = 42;
54
54
f($x);
55
- say $x; # 23
55
+ say $x; # OUTPUT: «23»
56
56
57
57
Inside the subroutine, the lexpad entry for C < $a > points to the same
58
58
container that C < $x > points to outside the subroutine. Which is why
@@ -63,7 +63,7 @@ Likewise a routine can return a container if it is marked as C<is rw>:
63
63
my $x = 23;
64
64
sub f() is rw { $x };
65
65
f() = 42;
66
- say $x; # 42
66
+ say $x; # OUTPUT: «42»
67
67
68
68
For explicit returns, C < return-rw > instead of C < return > must be used.
69
69
@@ -84,16 +84,16 @@ Scalar containers are transparent to type checks and most kinds of read-only
84
84
accesses. A C < .VAR > makes them visible:
85
85
86
86
my $x = 42;
87
- say $x.^name; # Int
88
- say $x.VAR.^name; # Scalar
87
+ say $x.^name; # OUTPUT: « Int»
88
+ say $x.VAR.^name; # OUTPUT: « Scalar»
89
89
90
90
And C < is rw > on a parameter requires the presence of a writable Scalar
91
91
container:
92
92
93
93
sub f($x is rw) { say $x };
94
94
f 42;
95
95
CATCH { default { say .^name, ': ', .Str } };
96
- # OUTPUT « X::Parameter::RW: Parameter '$x' expected a writable container, but got Int value »
96
+ # OUTPUT: «X::Parameter::RW: Parameter '$x' expected a writable container, but got Int value»
97
97
98
98
= head1 Binding
99
99
@@ -109,15 +109,15 @@ means that you cannot assign to it anymore:
109
109
my $x := 42;
110
110
$x = 23;
111
111
CATCH { default { say .^name, ': ', .Str } };
112
- # OUTPUT « X::AdHoc: Cannot assign to an immutable value »
112
+ # OUTPUT: «X::AdHoc: Cannot assign to an immutable value»
113
113
114
114
You can also bind variables to other variables:
115
115
116
116
my $a = 0;
117
117
my $b = 0;
118
118
$a := $b;
119
119
$b = 42;
120
- say $a; # 42
120
+ say $a; # OUTPUT: «42»
121
121
122
122
Here, after the initial binding, the lexpad entries for C < $a > and C < $b > both
123
123
point to the same scalar container, so assigning to one variable also
@@ -132,32 +132,30 @@ Sigilless variables also bind by default and so do parameters with the trait C<i
132
132
my $a = 42;
133
133
my \b = $a;
134
134
b++;
135
- say $a; # 43
135
+ say $a; # OUTPUT: «43»
136
136
137
137
sub f($c is raw) { $c++ }
138
138
f($a);
139
- say $a; # 44
139
+ say $a; # OUTPUT: «44»
140
140
141
141
= head1 Scalar containers and listy things
142
142
143
143
There are a number of positional container types with slightly different
144
144
semantics in Perl 6. The most basic one is L < List|/type/List >
145
145
It is created by the comma operator.
146
146
147
- say (1, 2, 3).^name; # List
147
+ say (1, 2, 3).^name; # OUTPUT: « List»
148
148
149
149
A list is immutable, which means you cannot change the number of elements
150
150
in a list. But if one of the elements happens to be a scalar container,
151
151
you can still assign to it:
152
152
153
153
my $x = 42;
154
154
($x, 1, 2)[0] = 23;
155
- say $x; # 23
156
- ($x, 1, 2)[1] = 23; # Error: Cannot modify an immutable value
155
+ say $x; # OUTPUT: «23»
156
+ ($x, 1, 2)[1] = 23; # Cannot modify an immutable value
157
157
CATCH { default { say .^name, ': ', .Str } };
158
- # OUTPUT:
159
- # 23
160
- # X::Assignment::RO: Cannot modify an immutable Int
158
+ # OUTPUT: «X::Assignment::RO: Cannot modify an immutable Int»
161
159
162
160
So the list doesn't care about whether its elements are values or
163
161
containers, they just store and retrieve whatever was given to them.
@@ -170,7 +168,7 @@ be containers, which means that you can always assign to elements:
170
168
171
169
my @a = 1, 2, 3;
172
170
@a[0] = 42;
173
- say @a; # 42 2 3
171
+ say @a; # OUTPUT: «[ 42 2 3]»
174
172
175
173
C < @a > actually stores three scalar containers. C < @a[0] > returns one of
176
174
them, and the assignment operator replaces the integer value stored in that
@@ -186,8 +184,8 @@ the same thing: discard the old value(s), and enter some new value(s).
186
184
187
185
Nevertheless, it's easy to observe how different they are:
188
186
189
- my $x = 42; say $x.^name; # Int
190
- my @a = 42; say @a.^name; # Array
187
+ my $x = 42; say $x.^name; # OUTPUT: « Int»
188
+ my @a = 42; say @a.^name; # OUTPUT: « Array»
191
189
192
190
This is because the C < Scalar > container type hides itself well, but C < Array >
193
191
makes no such effort. Also assignment to an array variable is coercive, so
@@ -196,7 +194,7 @@ you can assign a non-array value to an array variable.
196
194
To place a non-C < Array > into an array variable, binding works:
197
195
198
196
my @a := (1, 2, 3);
199
- say @a.WHAT; # (List)
197
+ say @a.WHAT; # OUTPUT: « (List)»
200
198
201
199
= head1 Binding to array elements
202
200
@@ -205,7 +203,7 @@ As a curious side note, Perl 6 supports binding to array elements:
205
203
my @a = (1, 2, 3);
206
204
@a[0] := my $x;
207
205
$x = 42;
208
- say @a; # 42 2 3
206
+ say @a; # OUTPUT: «[ 42 2 3]»
209
207
210
208
If you've read and understood the previous explanations, it is now time to
211
209
wonder how this can possibly work. After all, binding to a variable requires
@@ -229,7 +227,7 @@ counter-intuitive results when the array is used later.
229
227
@a[2] = $b; # ...but this is fine.
230
228
@a[1, 2] := 1, 2; # runtime error: X::Bind::Slice
231
229
CATCH { default { say .^name, ': ', .Str } };
232
- # OUTPUT « X::Bind::Slice: Cannot bind to Array slice »
230
+ # OUTPUT: «X::Bind::Slice: Cannot bind to Array slice»
233
231
234
232
Operations that mix Lists and Arrays generally protect against such
235
233
a thing happening accidentally.
@@ -249,23 +247,23 @@ do not flatten in list context:
249
247
250
248
my @a = 1, 2, 3;
251
249
my @b = @a, 4, 5;
252
- say @b.elems; # 3
250
+ say @b.elems; # OUTPUT: «3»
253
251
254
252
There are operations that flatten out sublists that are not inside a scalar
255
253
container: slurpy parameters (C < *@a > ) and explicit calls to C < flat > :
256
254
257
255
258
256
my @a = 1, 2, 3;
259
- say (flat @a, 4, 5).elems; # 5
257
+ say (flat @a, 4, 5).elems; # OUTPUT: «5»
260
258
261
259
sub f(*@x) { @x.elems };
262
- say f @a, 4, 5; # 5
260
+ say f @a, 4, 5; # OUTPUT: «5»
263
261
264
262
As hinted above, scalar containers prevent that flattening:
265
263
266
264
sub f(*@x) { @x.elems };
267
265
my @a = 1, 2, 3;
268
- say f $@a, 4, 5; # 3
266
+ say f $@a, 4, 5; # OUTPUT: «3»
269
267
270
268
The C < @ > character can also be used as a prefix to remove a scalar container:
271
269
@@ -289,15 +287,15 @@ user to L<handle|/type/Promise#method_in> timeouts.
289
287
my @a;
290
288
@a[0] = @a;
291
289
put @a.perl;
292
- # OUTPUT « (my \Array_54878224 = [Array_54878224,]) »
290
+ # OUTPUT: «(my \Array_54878224 = [Array_54878224,])»
293
291
294
292
= head1 Type Constraints
295
293
296
294
Any container can have a type constraint in form of a L < type object|/language/typesystem#Type_objects > or a L < subset|/language/typesystem#subset > . Both can be place between a declarator and the variable name or after the trait L < of|/type/Variable#trait_is_dynamic > . The constraint is a property of the container, not the variable. Any (re-)binding may change the type constraint or remove the constraint altogether if bound to a value instead of a container. Introspection of type constraints on containers is provided by C < .VAR.of > .
297
295
298
296
EVAL ‚my $i = 42; say $i.VAR.of; $i := "forty plus two"; say $i.VAR.of;‘;
299
297
CATCH { default { say .^name, ' ', .Str } }
300
- # OUTPUT « (Mu)X::Method::NotFound No such method 'of' for invocant of type 'Str' »
298
+ # OUTPUT: «(Mu)X::Method::NotFound No such method 'of' for invocant of type 'Str'»
301
299
302
300
303
301
= head1 Custom containers
@@ -322,9 +320,9 @@ work with types in Perl 6.
322
320
}
323
321
324
322
my Int $a := lucky(Int);
325
- say $a = 12;
323
+ say $a = 12; # OUTPUT: «12»
326
324
say $a = 'FOO'; # X::TypeCheck::Binding
327
- say $a = 13; # X::OutOfRange
328
- CATCH { default { say .^name, ': ', .Str; .resume } };
325
+ say $a = 13; # X::OutOfRange
326
+ CATCH { default { say .^name, ': ', .Str } };
329
327
330
328
= end pod
0 commit comments