@@ -1187,6 +1187,127 @@ operator:
1187
1187
say [42, "42"].squish(with => &infix:<eq>); # OUTPUT: «(42)»
1188
1188
# The resulting item is Int
1189
1189
1190
+ =head2 sub sleep
1191
+
1192
+ sub sleep($seconds = Inf --> Nil)
1193
+
1194
+ Attempt to sleep for the given number of C<$seconds>. Returns L<C<Nil>|/type/Nil> on
1195
+ completion. Accepts L<C<Int>|/type/Int>, L<C<Num>|/type/Num>, L<C<Rat>|/type/Rat>, or L<C<Duration>|/type/Duration> types as an
1196
+ argument since all of these also do L<C<Real>|/type/Real>.
1197
+
1198
+ =for code
1199
+ sleep 5; # Int
1200
+ sleep 5.2; # Num
1201
+ sleep (5/2); # Rat
1202
+ sleep (now - now + 5); # Duration
1203
+
1204
+ It is thus possible to sleep for a non-integer amount of time. For
1205
+ instance, the following code shows that C<sleep (5/2)> sleeps for 2.5
1206
+ seconds and C<sleep 5.2> sleeps for 5.2 seconds:
1207
+
1208
+ my $before = now;
1209
+ sleep (5/2);
1210
+ my $after = now;
1211
+ say $after-$before; # OUTPUT: «2.502411561»
1212
+
1213
+ $before = now;
1214
+ sleep 5.2;
1215
+ $after = now;
1216
+ say $after-$before; # OUTPUT: «5.20156987»
1217
+
1218
+ =head2 sub sleep-timer
1219
+
1220
+ sub sleep-timer(Real() $seconds = Inf --> Duration:D)
1221
+
1222
+ This function is implemented like C<sleep>, but unlike the former it does
1223
+ return a L<C<Duration>|/type/Duration> instance with the number of seconds the system did not
1224
+ sleep.
1225
+
1226
+ In particular, the returned L<C<Duration>|/type/Duration> will handle the number of seconds remaining
1227
+ when the process has been awakened by some external event (e.g., Virtual Machine
1228
+ or Operating System events).
1229
+ Under normal condition, when sleep is not interrupted, the returned L<C<Duration>|/type/Duration>
1230
+ has a value of C<0>, meaning no extra seconds remained to sleep.
1231
+ Therefore, in normal situations:
1232
+
1233
+ say sleep-timer 3.14; # OUTPUT: «0»
1234
+
1235
+ The same result applies to edge cases, when a negative or zero time to sleep
1236
+ is passed as argument:
1237
+
1238
+ =begin code
1239
+ say sleep-timer -2; # OUTPUT: 0
1240
+ say sleep-timer 0; # OUTPUT: 0
1241
+ =end code
1242
+
1243
+ See also L<sleep-until|/routine/sleep-until>.
1244
+
1245
+ =head2 sub sleep-until
1246
+
1247
+ sub sleep-until(Instant $until --> Bool)
1248
+
1249
+ Works similar to C<sleep> but checks the current time and keeps sleeping
1250
+ until the required instant in the future has been reached.
1251
+ It uses internally the C<sleep-timer> method in a loop to ensure that,
1252
+ if accidentally woken up early, it will wait again for the specified
1253
+ amount of time remaining to reach the specified instant.
1254
+ goes back to sleep
1255
+
1256
+ Returns C<True> if the L<C<Instant>|/type/Instant> in the future has been achieved (either
1257
+ by mean of sleeping or because it is right now), C<False> in the case
1258
+ an L<C<Instant>|/type/Instant> in the past has been specified.
1259
+
1260
+ To sleep until 10 seconds into the future, one could write something like this:
1261
+
1262
+ say sleep-until now+10; # OUTPUT: «True»
1263
+
1264
+ Trying to sleep until a time in the past doesn't work:
1265
+
1266
+ my $instant = now - 5;
1267
+ say sleep-until $instant; # OUTPUT: «False»
1268
+
1269
+ However if we put the instant sufficiently far in the future, the sleep
1270
+ should run:
1271
+
1272
+ =for code
1273
+ my $instant = now + 30;
1274
+ # assuming the two commands are run within 30 seconds of one another...
1275
+ say sleep-until $instant; # OUTPUT: «True»
1276
+
1277
+ To specify an exact instant in the future, first create a L<C<DateTime>|/type/DateTime> at the
1278
+ appropriate point in time, and cast to an L<C<Instant>|/type/Instant>.
1279
+
1280
+ =for code
1281
+ my $instant = DateTime.new(
1282
+ year => 2023,
1283
+ month => 9,
1284
+ day => 1,
1285
+ hour => 22,
1286
+ minute => 5);
1287
+ say sleep-until $instant.Instant; # OUTPUT: «True» (eventually...)
1288
+
1289
+ This could be used as a primitive kind of alarm clock. For instance, say
1290
+ you need to get up at 7am on the 4th of September 2015, but for some reason
1291
+ your usual alarm clock is broken and you only have your laptop. You can
1292
+ specify the time to get up (being careful about time zones, since
1293
+ C<DateTime.new> uses UTC by default) as an L<C<Instant>|/type/Instant> and pass this to
1294
+ C<sleep-until>, after which you can play an mp3 file to wake you up instead
1295
+ of your normal alarm clock. This scenario looks roughly like this:
1296
+
1297
+ =for code
1298
+ # DateTime.new uses UTC by default, so get time zone from current time
1299
+ my $timezone = DateTime.now.timezone;
1300
+ my $instant = DateTime.new(
1301
+ year => 2015,
1302
+ month => 9,
1303
+ day => 4,
1304
+ hour => 7,
1305
+ minute => 0,
1306
+ timezone => $timezone
1307
+ ).Instant;
1308
+ sleep-until $instant;
1309
+ qqx{mplayer wake-me-up.mp3};
1310
+
1190
1311
=head2 sub emit
1191
1312
1192
1313
sub emit(\value --> Nil)
0 commit comments