sub sleep-until

Documentation for sub sleep-until assembled from the following types:

class Date

From Date

(Date) sub sleep-until

sub sleep-until(Instant $until --> Bool)

Works similar to sleep but checks the current time and keeps sleeping until the required instant in the future has been reached. It uses internally the sleep-timer method in a loop to ensure that, if accidentally woken up early, it will wait again for the specified amount of time remaining to reach the specified instant. goes back to sleep

Returns True if the Instant in the future has been achieved (either by mean of sleeping or because it is right now), False in the case an Instant in the past has been specified.

To sleep until 10 seconds into the future, one could write something like this:

say sleep-until now+10;   # OUTPUT: «True␤» 

Trying to sleep until a time in the past doesn't work:

my $instant = now - 5;
say sleep-until $instant# OUTPUT: «False␤» 

However if we put the instant sufficiently far in the future, the sleep should run:

my $instant = now + 30;
# assuming the two commands are run within 30 seconds of one another... 
say sleep-until $instant# OUTPUT: «True␤» 

To specify an exact instant in the future, first create a DateTime at the appropriate point in time, and cast to an Instant.

my $instant = DateTime.new(
    year => 2020,
    month => 9,
    day => 1,
    hour => 22,
    minute => 5);
say sleep-until $instant.Instant# True (eventually...) 

This could be used as a primitive kind of alarm clock. For instance, say you need to get up at 7am on the 4th of September 2015, but for some reason your usual alarm clock is broken and you only have your laptop. You can specify the time to get up (being careful about timezones, since DateTime.new uses UTC by default) as an Instant and pass this to sleep-until, after which you can play an mp3 file to wake you up instead of your normal alarm clock. This scenario looks roughly like this:

# DateTime.new uses UTC by default, so get timezone from current time 
my $timezone = DateTime.now.timezone;
my $instant = DateTime.new(
    year => 2015,
    month => 9,
    day => 4,
    hour => 7,
    minute => 0,
    timezone => $timezone
).Instant;
sleep-until $instant;
qqx{mplayer wake-me-up.mp3};