如果不是 Nil,则变量重新分配方法结果
Variable re-assign method result if not Nil
是否有应用和分配对象变量方法调用的惯用方法,但前提是它已定义(方法和结果)?
喜欢使用safe call operator .?
and defined-or operator //
,并遵循“DRY原则”——在操作中只使用一次变量?
像这样(但使用另一个变量感觉像作弊):
my $nicevariable = "fobar";
# key step
(my $x := $nicevariable) = $x.?possibly-nonexistent-meth // $x;
say $nicevariable; # => possibly-nonexistent-meth (non-Nil) result or "foobar"
... 并尽可能避免 andthen
。
假设方法 returns 是 定义的东西,你可以这样做(如果我理解正确的话):
my $x = "foobar";
$x = $_ with $y.?possibly-nonexistent-meth;
$x
如果该方法不存在(或者它 确实 存在并返回一个类型对象)将保持不变。
我不完全确定“在操作中仅使用一次变量”是什么意思。如果 Liz 的回答符合条件,那么这可能是更简洁的方法。
如果不是,这里有一个不同的方法可以避免两次命名变量:
my $nicevariable = "foobar";
$nicevariable.=&{.^lookup('possibly-nonexistent-meth')($_)}
这对我来说有点太神秘了;这是它的作用:如果该方法存在,则类似于¹调用 &method($nicevariable)
,这与 $nicevariable.method
相同。如果该方法 不 存在,那么它就像调用 Mu($nicevariable)
– 也就是说,将 $nicevariable
强制转换为 Mu
或 [=16= 的子类型].但是因为一切都已经是 Mu
的子类型,所以这是一个空操作,只是 returns $nicevariable
.
[1]:不完全是,因为 &method
将是一个 Sub,但基本上。
编辑:
实际上,这太复杂了。这是一个更简单的版本:
my $nicevariable = "foobar";
$nicevariable.=&{.?possibly-nonexistent-meth // $_}
不知道为什么我不把它作为开始……
你知道 default trait 变量吗?
不确定它是否适合您的用例,但是 $some-var.?unknown-method
returns 无,所以:
my $nicevariable is default("fobar");
$nicevariable = $nicevariable.?possibly-nonexistent-meth;
say $nicevariable; # fobar
导致 $nicevariable
被重置为其默认值;
从 this merge 开始,您可以写:
try { let $foo .= bar }
这比我认为的理想解决方案差了一步,不幸的是这是一个语法错误(由于 Raku 的 current 语法中普遍存在的弱点,我' m 猜测实际上是无法解决的,就像我希望它被解决一样):
{ let $foo .?= bar } # Malformed postfix call...
(也许我在想象事情,但我看到了一丝希望,即上述皱纹(以及许多类似的皱纹)将在几年后被抚平。这将在 RakuAST 登陆 Raku 之后 .e
,语法有望在 Raku .f
或 .g
.)
中得到清理
你的问题的标题是:
Variable re-assign method result if not Nil
如果不是 undefined,我的解决方案会执行变量 re-assign 方法,这比 Nil
.
更通用
然后,您的问题 body 正是要求更通用的解决方案:
Is there idiomatic way of applying and assigning object variable method call, but only if it's defined (both method and the result)?
那么我的解决方案是理想的吗?
我的解决方案不是惯用的。但这很可能是因为我发现的错误,现在通过我回答开头链接的合并解决了。我看不出为什么它不应该 成为 惯用语,一旦它在运送 Rakudos 时。
潜在的大问题是 try
存储在 $!
中抛出的任何异常,而不是让它爆炸。对于给定的用例,这也许没问题;也许不是。
特别感谢您提出您的问题,这促使我们想出了各种解决方案,这导致我提交了一个问题,这导致 vrurg 既分析了我遇到的问题,又修复了它。 :)
是否有应用和分配对象变量方法调用的惯用方法,但前提是它已定义(方法和结果)?
喜欢使用safe call operator .?
and defined-or operator //
,并遵循“DRY原则”——在操作中只使用一次变量?
像这样(但使用另一个变量感觉像作弊):
my $nicevariable = "fobar";
# key step
(my $x := $nicevariable) = $x.?possibly-nonexistent-meth // $x;
say $nicevariable; # => possibly-nonexistent-meth (non-Nil) result or "foobar"
... 并尽可能避免 andthen
。
假设方法 returns 是 定义的东西,你可以这样做(如果我理解正确的话):
my $x = "foobar";
$x = $_ with $y.?possibly-nonexistent-meth;
$x
如果该方法不存在(或者它 确实 存在并返回一个类型对象)将保持不变。
我不完全确定“在操作中仅使用一次变量”是什么意思。如果 Liz 的回答符合条件,那么这可能是更简洁的方法。
如果不是,这里有一个不同的方法可以避免两次命名变量:
my $nicevariable = "foobar";
$nicevariable.=&{.^lookup('possibly-nonexistent-meth')($_)}
这对我来说有点太神秘了;这是它的作用:如果该方法存在,则类似于¹调用 &method($nicevariable)
,这与 $nicevariable.method
相同。如果该方法 不 存在,那么它就像调用 Mu($nicevariable)
– 也就是说,将 $nicevariable
强制转换为 Mu
或 [=16= 的子类型].但是因为一切都已经是 Mu
的子类型,所以这是一个空操作,只是 returns $nicevariable
.
[1]:不完全是,因为 &method
将是一个 Sub,但基本上。
编辑:
实际上,这太复杂了。这是一个更简单的版本:
my $nicevariable = "foobar";
$nicevariable.=&{.?possibly-nonexistent-meth // $_}
不知道为什么我不把它作为开始……
你知道 default trait 变量吗?
不确定它是否适合您的用例,但是 $some-var.?unknown-method
returns 无,所以:
my $nicevariable is default("fobar");
$nicevariable = $nicevariable.?possibly-nonexistent-meth;
say $nicevariable; # fobar
导致 $nicevariable
被重置为其默认值;
从 this merge 开始,您可以写:
try { let $foo .= bar }
这比我认为的理想解决方案差了一步,不幸的是这是一个语法错误(由于 Raku 的 current 语法中普遍存在的弱点,我' m 猜测实际上是无法解决的,就像我希望它被解决一样):
{ let $foo .?= bar } # Malformed postfix call...
(也许我在想象事情,但我看到了一丝希望,即上述皱纹(以及许多类似的皱纹)将在几年后被抚平。这将在 RakuAST 登陆 Raku 之后 .e
,语法有望在 Raku .f
或 .g
.)
你的问题的标题是:
Variable re-assign method result if not
Nil
如果不是 undefined,我的解决方案会执行变量 re-assign 方法,这比 Nil
.
然后,您的问题 body 正是要求更通用的解决方案:
Is there idiomatic way of applying and assigning object variable method call, but only if it's defined (both method and the result)?
那么我的解决方案是理想的吗?
我的解决方案不是惯用的。但这很可能是因为我发现的错误,现在通过我回答开头链接的合并解决了。我看不出为什么它不应该 成为 惯用语,一旦它在运送 Rakudos 时。
潜在的大问题是 try
存储在 $!
中抛出的任何异常,而不是让它爆炸。对于给定的用例,这也许没问题;也许不是。
特别感谢您提出您的问题,这促使我们想出了各种解决方案,这导致我提交了一个问题,这导致 vrurg 既分析了我遇到的问题,又修复了它。 :)