当原始变量具有默认强制转换时,有没有办法访问混合组件?
Is there a way to access mixed-in components when the original variable has a default coercion?
例如,在这种情况下:
my @list = (2,) but "bar";
put @list.Str «2»
似乎没有办法访问“栏”组件。我错过了什么吗?例如,Set
也会发生同样的情况
my @list = (2,3) but Set(4,5);
put @list.Set; # OUTPUT: «3 2»
赋值是复制操作,所以:
my @a = something;
在 @a
中创建一个 Array
,迭代 something
,并将每个元素存储在 @a
中。如果改为使用绑定:
my @list := (2,) but "bar";
put @list.Str;
然后将带有mixin的列表绑定到符号@list
,输出为:
bar
TL;DR 我想我现在更接近理解你的意思了。我在这个答案的开头分享了基于这种理解的各种解决方案。 (这个答案的其余部分现在可能大部分都没有实际意义,但我把它留了下来,因为我认为它仍然有一些价值,尤其是那个仍然让我困惑的明显错误。)
我现在认为你想要的一些解决方案
role foo { method Str { 42 } }
...
say @bar.Str; # 42
其中 ...
适当填写,例如:
-
class List2 is List does foo {}
my @bar is List2;
这是做什么的,什么时候:
创建一个新容器类型 List2
组成 List
角色 foo
.
永久将变量@bar
“绑定”到新容器类型的新实例。
所有这些都发生在编译时。
-
my @bar is List;
@bar does foo;
这是做什么的,什么时候:
永久 在编译时“绑定”变量 @bar
到 List
的新实例.
永久将foo
混合成相同的List
实例在运行-time.
-
my @bar := (1,2) but foo
这是做什么的,什么时候:
在编译时从文字 ((1,2)
).
构造一个新的 List
实例
在运行时间构造一个新实例,这是一个克隆List
的 从列表文字构造 但 与 foo
角色混合。
暂时“绑定”变量@bar
到newList
/ foo
对象 ((1,2) but foo
).
我的原回答
您共享的代码及其行为主要是基本的普通行为。 jnthn 的回答解释了这些基本方面。这个答案提供了更多细节,并指出了一个让我感到惊讶并且可能是错误的部分。
Is there a way to access mixed-in components when the original variable has a default coercion?
我想我看到了一些意想不到的事情,这可能就是你所说的。但我不会将其描述为“默认强制”,因为“默认”和“强制”在 Raku 中已经具有特定含义,并且与这些无关。模奇怪的行为,这只是 Raku 的普通语义,用于将复数值分配给复数变量。
For instance, in this case:
my @list = (2,) but "bar";
jnthn 的回答解释了为什么这行不通。简而言之,mixin 在复数值上,而不是在每个 within 复数值上,因此它不会作为赋值的一部分被复制。在您开始之前,您的代码已“损坏”。
你可以合理地编写这样的东西并期望它能工作:
my @list = (2,) Zbut "bar";
put @list.Str; # «bar»
第一行中的Z
使用zip将but
分布在复数List
值中的单数元素上but
] 语义。只有一个元素 -- 2
-- 但如果有更多元素,它也有效:
my @list = 2,3 Zbut "bar", "foo";
put @list.Str; # «bar foo»
清楚第二行中发生的事情很有用。
正在对 复数 值调用 .Str
方法(隐式创建并绑定到 @list
作为一部分的 Array
声明 my @list
).
与大多数编程语言一样,Raku 中的每个例程都主要根据其参数来决定要做什么。和大多数带有方法的 PL 一样,方法可能会根据它们的调用者做不同的事情。
在 Raku 中 .Str
方法,当使用 plural value/variable 调用 distributes a .Str
该复数调用者中的每个元素。 (如果它的任何元素本身是另一个复数,调用将递归地对其元素执行相同的操作。)完成所有操作后,生成的单个字符串系列将在每个字符串之间连接 space。
Same will happen, for instance, with Set
和以前一样,您将再次需要将 mixin 分发到第一行中的各个元素,以便有机会解决问题:
my @list = (2,3) Zbut Set(4,5);
但现在 second 行仍然无法满足您的预期:
put @list.Set; # OUTPUT: «3 2»
问题是这次你要处理 .Set
。
对复数调用 .Set
不同于对复数调用 .Str
。它具有完全不同的语义。它所做的是从复数值的元素集合构造一个集合。因此:
say (1,2,3).Set; # Set(1 2 3)
希望到目前为止这一切都有意义。
这里是让我感到惊讶的地方。这似乎有效:
my @list = 2 but Set(4,5);
put @list[0].^name; # OUTPUT: «Int+{<anon|1>}»
put @list[0].Set; # OUTPUT: «4 5»
put @list[0].Set.^name; # OUTPUT: «Set»
但是如果我们更改第一行,事情就不会像我预期的那样工作了:
my @list = (2,3) Zbut Set(4,5);
put @list[0].^name; # OUTPUT: «Int+{<anon|1>}»
put @list[0].Set; # OUTPUT: «2»
put @list[0].Set.^name; # OUTPUT: «Set»
这让我很困惑。我会睡在上面。但现在看来这可能是一个错误。
例如,在这种情况下:
my @list = (2,) but "bar";
put @list.Str «2»
似乎没有办法访问“栏”组件。我错过了什么吗?例如,Set
my @list = (2,3) but Set(4,5);
put @list.Set; # OUTPUT: «3 2»
赋值是复制操作,所以:
my @a = something;
在 @a
中创建一个 Array
,迭代 something
,并将每个元素存储在 @a
中。如果改为使用绑定:
my @list := (2,) but "bar";
put @list.Str;
然后将带有mixin的列表绑定到符号@list
,输出为:
bar
TL;DR 我想我现在更接近理解你的意思了。我在这个答案的开头分享了基于这种理解的各种解决方案。 (这个答案的其余部分现在可能大部分都没有实际意义,但我把它留了下来,因为我认为它仍然有一些价值,尤其是那个仍然让我困惑的明显错误。)
我现在认为你想要的一些解决方案
role foo { method Str { 42 } }
...
say @bar.Str; # 42
其中 ...
适当填写,例如:
-
class List2 is List does foo {} my @bar is List2;
这是做什么的,什么时候:
创建一个新容器类型
List2
组成List
角色foo
.永久将变量
@bar
“绑定”到新容器类型的新实例。所有这些都发生在编译时。
-
my @bar is List; @bar does foo;
这是做什么的,什么时候:
永久 在编译时“绑定”变量
@bar
到List
的新实例.永久将
foo
混合成相同的List
实例在运行-time.
-
my @bar := (1,2) but foo
这是做什么的,什么时候:
在编译时从文字 (
构造一个新的(1,2)
).List
实例在运行时间构造一个新实例,这是一个克隆
List
的 从列表文字构造 但 与foo
角色混合。暂时“绑定”变量
@bar
到newList
/foo
对象 ((1,2) but foo
).
我的原回答
您共享的代码及其行为主要是基本的普通行为。 jnthn 的回答解释了这些基本方面。这个答案提供了更多细节,并指出了一个让我感到惊讶并且可能是错误的部分。
Is there a way to access mixed-in components when the original variable has a default coercion?
我想我看到了一些意想不到的事情,这可能就是你所说的。但我不会将其描述为“默认强制”,因为“默认”和“强制”在 Raku 中已经具有特定含义,并且与这些无关。模奇怪的行为,这只是 Raku 的普通语义,用于将复数值分配给复数变量。
For instance, in this case:
my @list = (2,) but "bar";
jnthn 的回答解释了为什么这行不通。简而言之,mixin 在复数值上,而不是在每个 within 复数值上,因此它不会作为赋值的一部分被复制。在您开始之前,您的代码已“损坏”。
你可以合理地编写这样的东西并期望它能工作:
my @list = (2,) Zbut "bar";
put @list.Str; # «bar»
第一行中的Z
使用zip将but
分布在复数List
值中的单数元素上but
] 语义。只有一个元素 -- 2
-- 但如果有更多元素,它也有效:
my @list = 2,3 Zbut "bar", "foo";
put @list.Str; # «bar foo»
清楚第二行中发生的事情很有用。
正在对 复数 值调用 .Str
方法(隐式创建并绑定到 @list
作为一部分的 Array
声明 my @list
).
与大多数编程语言一样,Raku 中的每个例程都主要根据其参数来决定要做什么。和大多数带有方法的 PL 一样,方法可能会根据它们的调用者做不同的事情。
在 Raku 中 .Str
方法,当使用 plural value/variable 调用 distributes a .Str
该复数调用者中的每个元素。 (如果它的任何元素本身是另一个复数,调用将递归地对其元素执行相同的操作。)完成所有操作后,生成的单个字符串系列将在每个字符串之间连接 space。
Same will happen, for instance, with
Set
和以前一样,您将再次需要将 mixin 分发到第一行中的各个元素,以便有机会解决问题:
my @list = (2,3) Zbut Set(4,5);
但现在 second 行仍然无法满足您的预期:
put @list.Set; # OUTPUT: «3 2»
问题是这次你要处理 .Set
。
对复数调用 .Set
不同于对复数调用 .Str
。它具有完全不同的语义。它所做的是从复数值的元素集合构造一个集合。因此:
say (1,2,3).Set; # Set(1 2 3)
希望到目前为止这一切都有意义。
这里是让我感到惊讶的地方。这似乎有效:
my @list = 2 but Set(4,5);
put @list[0].^name; # OUTPUT: «Int+{<anon|1>}»
put @list[0].Set; # OUTPUT: «4 5»
put @list[0].Set.^name; # OUTPUT: «Set»
但是如果我们更改第一行,事情就不会像我预期的那样工作了:
my @list = (2,3) Zbut Set(4,5);
put @list[0].^name; # OUTPUT: «Int+{<anon|1>}»
put @list[0].Set; # OUTPUT: «2»
put @list[0].Set.^name; # OUTPUT: «Set»
这让我很困惑。我会睡在上面。但现在看来这可能是一个错误。