Как указывает JJMerelo в комментариях, способ, которым работает оператор ...
, заключается в продолжении генерации элементов на основе левых аргументов до тех пор, пока не будет точно достигнут правый аргумент (для каждого смарт-сопоставления).
Например, если мы создали последовательность, кратную 10,
my @tens = 0, 10, 20 ... 95;
say @tens[10]; # 100
say @tens[11]; # 110
Это потому, что не элемент @tens
на самом деле будет 95. Чтобы определить, является ли элемент последним, Оператор smartmatch (~~
) используется. Смарт-сопоставление DateTime
с другим Datetime
возвращает истину, если эти два представляют одно и то же время (которое может быть разным из-за часовых поясов, и т. Д. c).
Для последовательностей DateTime
дополнительно осложняется тем, что .later
и .earlier
не являются общими, поэтому выполнение $date.later(:1month).later(:1month)
не гарантирует того же результата, что и $date.later(:2month)
.
Причина, по которой * ≥ DateTime.new(…)
отличается, заключается в том, что интеллектуальное сопоставление для Callable
объектов (что технически так и есть, любой код, эквивалентный anon sub $dt { $dt ≥ DateTime.new(…) }
, передает левый аргумент вызываемому объекту. Если вы не уверены на 100%, что последовательность завершится при достижении точного значения, лучше всего использовать подход с любым кодом для обеспечения совпадения значения.