当应用于潜艇时,最初和返回是什么?

发布于 2025-02-10 19:50:30 字数 575 浏览 2 评论 0 原文

我在某个地方找到了操作员 and then ,当我在我发现了这一点:

#!/bin/env raku
sub load-data
{
  rand  > .5 or return; # simulated load data failure; return Nil
  (rand > .3 ?? 'error' !! 'good data') xx 10 # our loaded data 
}

load-data.first: /good/ andthen say "$_ is good";
# OUTPUT: «(good data is good)␤» 

load-data() andthen .return; # return loaded data, if it's defined 
die "Failed to load data!!";  

那么, .first 。返回在应用于Subs时工作? 我以前从未见过这样的事情。

I found the operator andthen somewhere, and when I looked it up in https://docs.raku.org/routine/andthen I found this:

#!/bin/env raku
sub load-data
{
  rand  > .5 or return; # simulated load data failure; return Nil
  (rand > .3 ?? 'error' !! 'good data') xx 10 # our loaded data 
}

load-data.first: /good/ andthen say "$_ is good";
# OUTPUT: «(good data is good)␤» 

load-data() andthen .return; # return loaded data, if it's defined 
die "Failed to load data!!";  

So, how do .first and .return work when applied to subs ?
I've never seen such things before.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

开始看清了 2025-02-17 19:50:30

那么, .first

不是。您没有调用 .first .trunt sub 对象上。

当Raku中的子例程没有参数出现时,就称为。因此,简单地将 load-data 用自己的呼叫 load-data ,就好像您要放置括号一样。 (注意:如果您想要获得子例程对象本身,则使用& sigil,所以& load-data 是子例程对象)因此,这

load-data.first: /good/ andthen say "$_ is good";

与更熟悉的类似python的语法中的类似内容相当。

load_data().first("good") and say(...)

首先, load-data 被调用。它返回 nil 或数据列表。现在 在列表上调用。

返回列表的第一个项目,该列表对 $ Matcher ,返回 nil 当不匹配时。可选命名参数:end 表示搜索应来自列表的末尾,而不是从开始。

您已将其称为 load-data.first:/good/,因此它将返回正则表达式/good/good/匹配的列表的第一个元素,或 nil 否则。

andthen 就像&&& ,除了&& 检查真实性(通过布尔上下文)检查,和Thenen 通过多方法 定义 nil 和故障之类的对象是未定义的,而大多数“普通”对象(例如数字和字符串)是定义的。特别是,仍然定义了常规“虚假”(例如零或空字符串)的事物。像&& 和thenen 短路,因此,如果左侧不确定,则右侧永远不会评估。

最后,还有另一个怪癖使这条线可以工作。 和Thens 旨在处理此确切的用例:做事情1,如果那件事成功,请执行操作2。通常,事物2取决于事物1的结果。 /code>在评估右侧时,将左侧的结果分配给特殊变量 $ _ 。那是一口气的,所以让我们把它写出来。 X和Then Y 执行以下操作。

  1. 评估 X
  2. 如果未定义 X ,请停止。我们完成了。返回 x
  3. 否则,将 $ _ 设置为 x 的结果。
  4. 现在评估 y (使用 $ _ 设置)并将其返回。

因此,将所有内容全部放入...

load-data.first: /good/ andthen say "$_ is good";

加载数据,找到与正则匹配的加载数据的第一个元素,如果存在,则将其打印出来。

现在让我们看看您的第二个示例。您需要了解另一个有趣的小糖糖。通常,语句开头的点带有隐含的 $ _ 。因此, .say 等于 $_。Say,它等效于 say($ _:),该方法在方法分辨率为<<<<<等效。代码>说($ _)。

你相信与否, return 是子例程。严重地。这不是关键字;这是一个子。返回&amp; return.s repl中的。它会说(sub)

load-data() andthen .return;
die "Failed to load data!!";

load-data 被调用,如果返回定义的任何内容,则定义的值将分配给 $ _ 。然后。返回发生,这等效于 $_。返回哪个(最终)变为返回($ _)。如果定义了值,则它将从函数返回,第二行永远不会运行。如果没有,我们 die 带有适当的错误消息。

请注意,在这种情况下,实际上需要括号。如果我们编写

load-data andthen .return;

,则Raku试图将和Then.Return 作为参数 load> load-data ,并抱怨没有subroutine称为 and and < /代码>存在。它认为我们的意思是

load-data(andthen(.return));

总而言之,Raku是一个大包,里面装满了语法糖,该糖包裹在地狱第六个地狱中的解析器中,这是一个敏感的,其结果是一种真正美丽的语言。

So, how do .first and .return work when applied to subs ?

It doesn't. You're not calling .first or .return on a Sub object.

When a subroutine in Raku appears with no arguments, it's called. So simply writing load-data on its own calls load-data, as though you'd put parentheses. (Note: If you want to get the subroutine object itself, you use an & sigil, so &load-data is the subroutine object) So this

load-data.first: /good/ andthen say "$_ is good";

is equivalent to something like this in a more familiar Python-like syntax.

load_data().first("good") and say(...)

First, load-data is called. It returns either Nil or a list of data. Now first is called on the list.

Returns the first item of the list which smartmatches against $matcher, returns Nil when no values match. The optional named parameter :end indicates that the search should be from the end of the list, rather than from the start.

You've called it as load-data.first: /good/, so it will return the first element of the list for which the regular expression /good/ matches, or Nil otherwise.

andthen is like &&, except that while && checks for truthiness (via a Boolean context), andthen checks for definedness via the multi method defined. Objects like Nil and failures are undefined, while most "ordinary" objects like numbers and strings are defined. In particular, things that are conventionally "falsy" like zero or the empty string are still defined. Like &&, andthen short-circuits, so if the left-hand side is undefined, then the right-hand side never evaluates.

Finally, there's one other quirk that enables this line to work. andthen is designed to work with this exact use case: Do thing 1 and, if that thing succeeds, do thing 2. Frequently, thing 2 depends on the result of thing 1. So andthen assigns the result of the left-hand side to the special variable $_ during evaluation of the right-hand side. That's a mouthful, so let's write it out. x andthen y does the following.

  1. Evaluate x.
  2. If x is not defined, then stop. We're done. Return x.
  3. Otherwise, set $_ to the result of x.
  4. Now evaluate y (with $_ set) and return it.

So, taking it all in...

load-data.first: /good/ andthen say "$_ is good";

Load the data, find the first element of the loaded data which matches a regex, and if one exists, then print it out.

Now let's take a look at your second example. There's another fun little piece of syntax sugar you need to know about for this one. In general, a dot at the beginning of a statement carries an implied $_. So .say is equivalent to $_.say, which is equivalent to say($_:), which evaluates after method resolution to say($_).

And believe it or not, return is a subroutine. Seriously. It's not a keyword; it's a sub. Go evaluate &return.WHAT in your REPL right now. It'll say (Sub).

load-data() andthen .return;
die "Failed to load data!!";

load-data gets called, and if it returns anything defined, that defined value gets assigned to $_. Then .return happens, which is equivalent to $_.return which (eventually) becomes return($_). If the value was defined, it gets returned from the function and the second line never runs. If not, we die with an appropriate error message.

Note that the parentheses are actually required in this case. If we write

load-data andthen .return;

Then Raku tries to interpret andthen .return as an argument to load-data and complains that no subroutine called andthen exists. It thinks we meant

load-data(andthen(.return));

In summary, Raku is a big bag full of syntax sugar wrapped in a parser from the sixth circle of Hell that's whitespace- and context- sensitive, and the result is a genuinely beautiful language.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文