3.days.ago Perl6 中的实现

3.days.ago implementation in Perl6

我想实现像 3.days.ago2.months.from_now 这样的时间计算。 是否可以将方法扩展到 Int,或者运算符覆盖可以做到这一点?

1.day.ago      # equivalent to yesterday
1.day.from_now # equivalent to tomorrow

扩展现有 class 的基本方法是扩充它:

use MONKEY-TYPING;
augment class Int {
    method day() { "day" }
}
say 42.day

从那里您可以让 "day" 方法创建一个可以处理 "ago" 和 "from_now" 方法的对象。

请注意,您似乎需要稍微考虑一下 API:在第一行中,1.day 似乎指的是今天,而在第二行中只有 "from_now" 似乎有那个功能。

请注意,目前子classes 不知道 superclasses 正在增强:这是一个已知问题。目前解决这个问题的唯一方法是在增加它们的 superclass:

之后重新组合你需要的 subclasses
use MONKEY-TYPING;
augment class Cool {  # Int is a subclass of Cool
    method day() { "day" }
}
BEGIN Int.^compose; # make sure Int knows about ".day"
say 42.day

为了得到你想要的:

use MONKEY-TYPING;
augment class Int {

    my class Date::Offset {
        has Pair $.offset is required;

        method ago () {
            Date.today.earlier( |$!offset )
        }

        method from-now () {
            Date.today.later( |$!offset )
        }
    }

    method days () {
        Date::Offset.new( offset => days => self );
    }
    method months () {
        Date::Offset.new( offset => months => self );
    }
}

say 1.days.ago;      # 2017-03-13
say Date.today;      # 2017-03-14
say 1.days.from-now; # 2017-03-15

say 1.months.ago;    # 2017-02-14

既然我已经向您展示了如何操作,请不要这样做。您最终可能会以一种很难排除故障的方式影响您不打算影响的代码。
(有正当理由做这样的事情,但我不认为这是其中之一)

如果您想弄乱基本操作的发生方式,请按词法进行。

{
    sub postfix:« .days.ago » ( Int:D $offset ) {
        Date.today.earlier( days => $offset )
    }

    sub postfix:« .days.from-now » ( Int:D $offset ) {
        Date.today.later( days => $offset )
    }

    sub postfix:« .months.ago » ( Int:D $offset ) {
        Date.today.earlier( months => $offset )
    }

    sub postfix:« .months.from-now » ( Int:D $offset ) {
        Date.today.later( months => $offset )
    }

    say 1.days.ago;      # 2017-03-13
    say Date.today;      # 2017-03-14
    say 1.days.from-now; # 2017-03-15

    say 1.months.ago;    # 2017-02-14

}

say 1.days.ago; # error

use MONKEY-TYPING 可能会很有趣,但如果你真的只是想计算日期,那么请使用内置的 Date 对象:

put Date.today;                 # 2017-03-23
put Date.today.earlier(day=>3); # 2017-03-20
put Date.today.later(month=>3); # 2017-06-23

(我知道 , but am glad to have been )。