为什么不能在没有滑动的情况下将手动创建的 Pair 传递给方法?

Why can't pass a manually created Pair to method without a slip?

:5hours是一个Pairhours => 5也是一个Pair:

> DateTime.now.truncated-to('day').later(:5hours)
2022-02-14T05:00:00+08:00
> :5hours.WHAT
(Pair)

> DateTime.now.truncated-to('day').later(hours => 5)
2022-02-14T05:00:00+08:00
> (hours => 5).WHAT
(Pair)

但是,当我手动创建 Pair 时,它与 later:

的签名不匹配
> DateTime.now.truncated-to('day').later(Pair.new('hours', 5))
Cannot resolve caller later(DateTime:D: Pair:D); none of these signatures match:
    (Dateish:D: *%unit --> Dateish:D)
    (Dateish:D: @pairs, *%_)
  in block <unit> at <unknown file> line 1

但是在Pair参数之前用一个垂直的就可以了:

> DateTime.now.truncated-to('day').later(|Pair.new('hours', 5))
2022-02-14T05:00:00+08:00

那么:5hoursPair.new('hours', 5)hours => 5有什么区别呢?为什么不能将手动创建的 PairPair.new('hours', 5) 传递给 later 方法?

下面这两个不是一回事吧?

> :5hours === Pair.new('hours', 5) === hours => 5
True
> :5hours eqv Pair.new('hours', 5) eqv hours => 5
True

> my $pair1 = Pair.new('hours', 5); dd $pair1; # Pair $pair1 = :hours(5)
> my $pair2 = :5hours; dd $pair2;              # Pair $pair2 = :hours(5)
> my $pair3 = hours => 5; dd $pair3;           # Pair $pair3 = :hours(5)
> my $pair4 = 'hours' => 5; dd $pair4;         # Pair $pair4 = :hours(5)

虽然:5hourshours => 5:hours(5)Pair.new(hours,5)Pair.new(key => "hours", value => 5)都是创建Pair对象的不同方法,只有前三个 是表示命名参数的语法糖

当您将 Pair.new("hours",5) 作为参数传递时,它被视为 Positional 参数。观察:

sub foo(*@_, *%_) {
    dd @_, %_
}

foo hours => 5;
# []
# {:hours(5)}

foo Pair.new("hours",5);
# [:hours(5)]
# {}

至于为什么会这样?好吧,有时你想传递一个 Pair 作为位置参数。如果 Pair 始终被认为是命名参数,您将无法这样做。

至于为什么 |Pair.new("hours",5) 作为命名参数?此上下文中的 | 将给定对象(通常是 CaptureHash/Map)展平为给定子例程的参数。在这种情况下,Pair 被视为 Map 的退化情况:具有单个键/值的不可变 Map。观察:

foo |Pair.new("hours",5);
# []
# {:hours(5)}

嗯,可能是 Associative :-)

say Pair ~~ Associative;    # True
.say for (:5hours).keys;    # hours
.say for (:5hours).values;  # 5

最后,此上下文中的 | 在技术上 不是 一个 Slip,而是将给定值扁平化为调用参数的语法糖.

语法早于 Slip 的概念(2015 年在 Great List Refactor 期间引入)。只是在 2015 年很晚的时候,| 才被@Larry 确定也可以用来表示 Slip,因为他们 概念上 做类似的事情。