@@ -113,6 +113,8 @@ You can assign to multiple keys at the same time with a slice.
113
113
114
114
= head2 Non-string keys
115
115
116
+ X < |non-string keys > X < |:{} >
117
+
116
118
By default keys in C < { } > are forced to strings. To compose a hash with
117
119
non-string keys, use a colon prefix:
118
120
@@ -127,6 +129,63 @@ Note: The same pitfalls explained about C<{}> sometimes creating Block's also
127
129
apply to C < :{} > . At this time there is no C < %() > version for creating non-string
128
130
keys.
129
131
132
+ Hash keys are stored as L < Str > values in a normal hash. In many cases this is
133
+ sufficient, but sometimes you want the hash to preserve the objects you are using
134
+ as keys I < as the *exact* objects you are providing to the hash to use as keys > .
135
+ In these moments you want an object hash!
136
+
137
+ my %intervals{Instant};
138
+ my $first-instant = now;
139
+ %intervals{ $first-instant } = "Our first milestone.";
140
+ sleep 1;
141
+ my $second-instant = now;
142
+ %intervals{ $second-instant } = "Logging this Instant for spurious raisins.";
143
+ for %intervals.sort -> (:$key, :$value) {
144
+ state $last-instant //= $key;
145
+ say "We noted '$value' at $key, with an interval of {$key - $last-instant}";
146
+ $last-instant = $key;
147
+ }
148
+
149
+ This example uses an object hash that only accepts keys of type L < Instant > to
150
+ implement a rudimentary, yet type-safe, logging mechanism. We utilize a named L < state|/language/variables#The_state_Declarator >
151
+ variable for keeping track of the previous C < Instant > so that we can provide an interval.
152
+
153
+ The whole point of object hashes is to keep keys as objects-in-themselves.
154
+ Currently object hashes utilize the L < WHICH|/routine/WHICH > method of an object, which returns a
155
+ unique identifier for every mutable object. This is the keystone upon which the object
156
+ identity operator (L < === > ) rests. Order and containers really matter here as the order of
157
+ C < .keys > is undefined and one anonymous list is never L < === > to another.
158
+
159
+ my %intervals{Instant};
160
+ my $first-instant = now;
161
+ %intervals{ $first-instant } = "Our first milestone.";
162
+ sleep 1;
163
+ my $second-instant = now;
164
+ %intervals{ $second-instant } = "Logging this Instant for spurious raisins.";
165
+ say ($first-instant, $second-instant) ~~ %intervals.keys; # OUTPUT: «False»
166
+ say ($first-instant, $second-instant) ~~ %intervals.keys.sort; # OUTPUT: «False»
167
+ say ($first-instant, $second-instant) === %intervals.keys.sort; # OUTPUT: «False»
168
+ say $first-instant === %intervals.keys.sort[0]; # OUTPUT: «True»
169
+
170
+ Since C < Instant > defines its own comparison methods, in our example a sort according to
171
+ L < cmp > will always provide the earliest instant object as the first element in the L < List >
172
+ it returns.
173
+
174
+ If you would like to accept any object whatsoever in your hash, you can use L < Any > !
175
+
176
+ my %h{Any};
177
+ %h{(now)} = "This is an Instant";
178
+ %h{(DateTime.now)} = "This is a DateTime, which is not an Instant";
179
+ %h{"completely different"} = "Monty Python references are neither DateTimes nor Instants";
180
+
181
+ There is a more concise syntax which uses binding.
182
+
183
+ my %h := :{ (now) => "Instant", (DateTime.now) => "DateTime" };
184
+
185
+ The binding is necessary because an object hash is about very solid, specific objects,
186
+ which is something that binding is great at keeping track of but about which assignment doesn't
187
+ concern itself much.
188
+
130
189
= head2 Constraint value types
131
190
132
191
Place a type object in-between the declarator and the name to constraint the type
@@ -204,66 +263,6 @@ pairs can be accessed in the same way as with plain C<.kv>:
204
263
You can also loop over a C < Hash > using
205
264
L < destructuring|/type/Signature#Destructuring_Parameters > .
206
265
207
- = head2 Object hashes and type constraints
208
- X < |object hash > X < |:{} >
209
-
210
- Hash keys are stored as L < Str > values in a normal hash. In many cases this is
211
- sufficient, but sometimes you want the hash to preserve the objects you are using
212
- as keys I < as the *exact* objects you are providing to the hash to use as keys > .
213
- In these moments you want an object hash!
214
-
215
- my %intervals{Instant};
216
- my $first-instant = now;
217
- %intervals{ $first-instant } = "Our first milestone.";
218
- sleep 1;
219
- my $second-instant = now;
220
- %intervals{ $second-instant } = "Logging this Instant for spurious raisins.";
221
- for %intervals.sort -> (:$key, :$value) {
222
- state $last-instant //= $key;
223
- say "We noted '$value' at $key, with an interval of {$key - $last-instant}";
224
- $last-instant = $key;
225
- }
226
-
227
- This example uses an object hash that only accepts keys of type L < Instant > to
228
- implement a rudimentary, yet type-safe, logging mechanism. We utilize a named L < state|/language/variables#The_state_Declarator >
229
- variable for keeping track of the previous C < Instant > so that we can provide an interval.
230
-
231
- The whole point of object hashes is to keep keys as objects-in-themselves.
232
- Currently object hashes utilize the L < WHICH|/routine/WHICH > method of an object, which returns a
233
- unique identifier for every mutable object. This is the keystone upon which the object
234
- identity operator (L < === > ) rests. Order and containers really matter here as the order of
235
- C < .keys > is undefined and one anonymous list is never L < === > to another.
236
-
237
- my %intervals{Instant};
238
- my $first-instant = now;
239
- %intervals{ $first-instant } = "Our first milestone.";
240
- sleep 1;
241
- my $second-instant = now;
242
- %intervals{ $second-instant } = "Logging this Instant for spurious raisins.";
243
- say ($first-instant, $second-instant) ~~ %intervals.keys; # OUTPUT: «False»
244
- say ($first-instant, $second-instant) ~~ %intervals.keys.sort; # OUTPUT: «False»
245
- say ($first-instant, $second-instant) === %intervals.keys.sort; # OUTPUT: «False»
246
- say $first-instant === %intervals.keys.sort[0]; # OUTPUT: «True»
247
-
248
- Since C < Instant > defines its own comparison methods, in our example a sort according to
249
- L < cmp > will always provide the earliest instant object as the first element in the L < List >
250
- it returns.
251
-
252
- If you would like to accept any object whatsoever in your hash, you can use L < Any > !
253
-
254
- my %h{Any};
255
- %h{(now)} = "This is an Instant";
256
- %h{(DateTime.now)} = "This is a DateTime, which is not an Instant";
257
- %h{"completely different"} = "Monty Python references are neither DateTimes nor Instants";
258
-
259
- There is a more concise syntax which uses binding.
260
-
261
- my %h := :{ (now) => "Instant", (DateTime.now) => "DateTime" };
262
-
263
- The binding is necessary because an object hash is about very solid, specific objects,
264
- which is something that binding is great at keeping track of but about which assignment doesn't
265
- concern itself much.
266
-
267
266
= head2 In place editing of values
268
267
269
268
There may be times when you would like to modify the values of a hash while iterating over them.
0 commit comments