如何解决在 Raku 中不创建字符串上下文的情况下进行插值?
如果我有一个变量 my $a = True
,那么我从下面的代码中得到这个输出:
say «a list of words foo $a bar baz».raku;
# OUTPUT: ("a","list","of","words","foo","True","bar","baz")
也就是说,即使结果是 List
,元素 True
在被包含在列表中之前被字符串化——列表包含 "True"
,而不是 True
。有什么办法可以在仍然使用插值的同时避免这种字符串化?
如果 $a
是我定义的类(因此可以为其编写 Str
方法)而不是 Bool
,有没有办法做到这一点?
(我知道我可以写更详细的 ("a",$a,"baz")
或 «a list of words foo».Slip,«bar baz».Slip
,但我想知道是否有办法仍然使用插值)。
解决方法
插值是将一个东西放入一个字符串中。
"a b c $thing d e f"
它首先将事物本身变成一个字符串,然后将字符串的其余部分串联起来。
基本上上面编译成这个代码:
infix:<~>( 「a b c 」,$thing.Str,「 d e f」 )
« a b c $thing »
简称:
Q :double :quotewords « a b c $thing d e f »
即使用 Q
uoting DSL,打开 :double
引号语义 (“”
) 并打开 :quotewords
。
:quotewords
是将字符串拆分为各个部分的功能。
它只有在变成字符串后才会发生。
想象一下,上面编译成:
Internals::quotewords( infix:<~>( 「 a b c 」,「 d e f 」 ) )
除了使用 .Slip
或前缀 |
之外,还有另一种方式可以获得您想要的东西。
flat «a list of words foo»,$a,«bar baz»
引用 DSL 的全部目的是生成一个字符串。
也就是说,:words
、:quotewords
和 :val
都对其进行了更改,使其返回的不是单个字符串。
他们的想法是改变 DSL。
所以可能你可以说服足够多的人相信这样的改变是值得的。 这是一个很大的可能。
它可能会破坏许多现有的代码库,因此您将面临一场艰苦的战斗。
,这里发生的事情与引用无关,而与 context 有很大关系。正如@brad-gilbert 所指出的,任何经过的过程都通过将 ~
放在前面,这会将变量强制转换为 String
上下文。
但这可以回答您的第二个问题:
如果 $a 是我定义的类(因此可以为其编写 Str 方法)而不是 Bool,有没有办法做到这一点?
理论上,这样的事情应该可行:
class A {
has Bool $.foo;
method Str { $.foo }
};
my $a = A.new( :foo(True) );
say «a b $a».raku
唉,这会返回 «No such method 'WORDS_AUTODEREF' for invocant of type 'Bool'
所以它可能需要一些工作(或者我可能遇到了一些错误)。因此,就您的具体示例而言,这暂时是一个 nanswer。事实上,只有 Str
有这个方法,所以我认为暂时没有,除非你费心为一个类创建那个专门的方法,否则很难做到。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。