字符串上的 Raku 范围运算符可以模仿 Perl 的行为吗?

Can Raku range operator on strings mimic Perl's behaviour?

在 Perl 中,表达式 "aa" .. "bb" 创建一个包含以下字符串的列表:

aa ab ac ad ae af ag ah ai aj ak al am an ao ap aq ar as at au av aw ax ay az ba bb

然而,在 Raku 中(至少对于 Rakudo v2021.08),相同的表达式创建:

aa ab ba bb

更糟糕的是,Perl 中的 "12" .. "23" 创建了一个字符串列表,其中包含数字 12, 13, 14, 15, ..., 23,而在 Raku 中,相同的表达式创建了列表 ("12", "13", "22", "23").

文档似乎对这种行为保持沉默;至少,我在那里找不到解释。有什么方法可以获取 Perl 对 Raku 范围的行为?

(我知道第二个问题可以通过类型转换为 Int 来解决。但这不适用于第一个问题。)

通过使用带有自定义生成器的 sequence 可以获得 Perl 行为:

say 'aa', *.succ … 'bb';
# OUTPUT: «aa ab ac ad ae af ag ah ai aj ak al am an ao ap aq ar as at au av aw ax ay az ba bb»

say '12', *.succ … '23';
# OUTPUT: «12 13 14 15 16 17 18 19 20 21 22 23»

(哦,'12'..'23' 案例的一半解决方案:您已经注意到您可以将端点转换为数字类型以获得您想要的输出。但您实际上不需要转换两个端点 - 只是底部。所以 12..'23' 仍然会产生完整的输出。作为必然结果,因为 ^'23'0..^'23' 的糖分,任何使用 &prefix:<^> 构建的范围都将是数字.)

对于此行为背后的“原因”,请参阅我对此问题的

TL;DR 向端点字符串添加一个或多个额外字符。字符 is/are.

是什么并不重要

当前的文档语料库被 Moritz Lenz++ 启动 10 年后,Raku 的文档一如既往地在进行中。

有一个超过 16 年的聊天记录的金矿,我有时会在其中寻找答案。 A search for range "as words" with nick: TimToady netted me this 几分钟后:

TimToady beginning and ending of the same length now do the specced semantics

considering each position as a separate character range

我的即时反应:

  • 这就是为什么它会这样做的原因。设计 Perl 范围如何工作的人不仅故意指定它在 Raku 中如何工作,而且在 2015 年亲自在 Rakudo 中实现了它。

  • 它做到了iff​​“开始和结束的长度相同”。唔。

几秒后:

say flat "aa" .. "bb (like perl)";
say flat "12" .. "23 (like perl)";

显示:

(aa ab ac ad ae af ag ah ai aj ak al am an ao ap aq ar as at au av aw ax ay az ba bb)
(12 13 14 15 16 17 18 19 20 21 22 23)

[我将其拆分为一个单独的答案,因为它解决了“为什么”而不是“如何”]

我做了一些挖掘,了解到:

  1. 对于序列"aa"…"bb"产生"aa", "ab", "ba", "bb"specified in Roast
  2. original use case provided for this behavior was generating sequences of octal numbers (as Strs) (discussed again in 2018)
  3. 对于 Ranges"aa".."bb" 的行为目前未指定,并且似乎没有就它的内容达成共识应该是。
  4. (如您所知),Rakudo 的实现 "aa".."bb""aa"…"bb".
  5. 的行为相同
  6. 2018 年,lizmat ([Elizabeth Mattijsen])https://whosebug.com/users/7424470/elizabeth-mattijsen) on Whosebug) changed .. to make "aa".."bb" behave the way it does in Perl but reverted 改变了对正确行为的未决共识。

所以我想我们(作为一个社区)还在考虑这个问题?就个人而言,我倾向于同意 lizmat 的观点,即让 "aa".."bb" 提供更长的范围(如 Perl)是有道理的:如果用户想要更短的范围,他们可以使用序列。 (或者,对于八进制范围,类似于 (0..0o377).map: *.fmt('%03o')

但是,无论哪种方式,我绝对同意 2018 年的承诺,即我们应该将其固定在 Roast 中——然后在文档中注明。