我怀疑这个问题很容易回答,答案是否定的。但是,我想确保我没有遗漏任何东西。
考虑以下代码:
sub f(:$a = 'foo') { say $a }
sub g(:$a) { f :$a }
g(); # OUTPUT: «(Any)»
Run Code Online (Sandbox Code Playgroud)
有没有一种好方法可以更改&f
or的签名/正文,&g
以便打印foo
而不是Any
?
我知道有两种方法可以&f
使用 的默认值$a
,但它们都不是很好。
选项1:
sub f(:$a = 'foo') { say $a }
multi g(:$a) { f :$a }
multi g() { f }
g(); # OUTPUT: «foo»
Run Code Online (Sandbox Code Playgroud)
选项 2:
sub f(:$a = 'foo') { say $a }
sub g(:$a) { f |(:$a with $a) }
g(); # OUTPUT: …
Run Code Online (Sandbox Code Playgroud) 如果我有一个变量my $a = True
,那么我从下面的代码中得到这个输出:
say «a list of words foo $a bar baz».raku;
# OUTPUT: ("a", "list", "of", "words", "foo", "True", "bar", "baz")
Run Code Online (Sandbox Code Playgroud)
也就是说,即使结果是 a List
,元素True
在被包含在列表中之前也会被字符串化——列表包含"True"
,而不是True
。有什么方法可以在仍然使用插值的同时避免这种字符串化?
如果$a
是我定义的类(因此可以Str
为其编写方法)而不是 ,那么有没有办法做到这一点Bool
?
(我知道我可以写更详细的("a", "list", "of", "words", "foo", $a, "bar", "baz")
or «a list of words foo».Slip, $a, «bar baz».Slip
,但我问是否有办法仍然使用插值)。
在下面的代码中,正则表达式$r
清楚地“知道”它包含文本bar
——这就是它能够与 Str 匹配的方式bar
。但是.gist
并.raku
报告$r
包含变量$foo
而不说明值$foo
包含什么。有什么办法可以$r
告诉我它的计算值吗?
sub f {
my $foo = 'bar';
g(rx/$foo/);
}
sub g($r) {
say $r.gist;
say 'bar' ~~ rx/$r/;
}
f # OUTPUT: rx/$foo/
# ?bar?
Run Code Online (Sandbox Code Playgroud)
(我知道我可以通过手动解析访问相同的信息$r
,发现所有的变量,然后走&g
的callframe
s中变量的值。但是,这似乎是一个相当脆弱的黑客得到的信息是,正则表达式显然已经知道,至少在某种程度上。)
当 proto 和 multis 在同一个模块中定义时,Type.^lookup('method').candidates
返回所有多候选者的列表。但是,当 proto 与 multis 位于不同的文件/模块中时,这似乎不起作用。
say Setty.^lookup('grab').candidates; # OUTPUT: ()
Run Code Online (Sandbox Code Playgroud)
有没有办法通过Raku的自省找到完整的多候选人名单?或者除了搜索源代码之外别无选择?(我问是因为拥有适用于给定 proto 的多候选者的完整列表将有助于文档目的。)
考虑以下两个程序:
unit module Comp;
say 'Hello, world!'
Run Code Online (Sandbox Code Playgroud)
和
unit module Comp;
CHECK { if $*DISTRO.is-win { say 'compiling on Windows' }}
say 'Hello, world!'
Run Code Online (Sandbox Code Playgroud)
天真地,我希望两个程序编译成完全相同的字节码:CHECK
块指定在编译结束时运行的代码;检查一个变量然后什么都不做对程序的运行时行为没有影响,因此(我原以为)不需要包含在编译的字节码中。
然而,编译这两个方案并没有产生相同的字节码。具体来说,编译没有CHECK
块的版本会创建 24K 的字节码,而带有它的版本则是 60K。为什么这两个版本的字节码不同?字节码中的这种差异是否具有(或可能具有)运行时成本?(似乎必须如此,但我想确定一下)。
还有一个相关的问题:DOC CHECK
块如何与上述内容相适应?我的理解是,即使编译器DOC CHECK
在不使用--doc
标志运行时也会跳过块。与此一致,当给定一个像上面那样的块时,hello-world 程序的字节码不会增加大小DOC CHECK
。但是,如果块包含语句,它的大小确实会增加use
。由此,我得出结论,这use
是某种特殊情况,即使在DOC CHECK
块中也能执行。那是对的吗?如果是这样,还有其他类似的特殊形式我应该知道吗?
如果我有以下变量
my $a = 0;
my $*b = 1;
state $c = 2;
our $d = 3;
Run Code Online (Sandbox Code Playgroud)
我可以很容易地确定这$*b
是动态的,但$a
不是下面的代码
say $a.VAR.dynamic;
say $*b.VAR.dynamic;
Run Code Online (Sandbox Code Playgroud)
有什么方法可以类似地确定它$c
是状态变量$d
还是包范围的变量?(我知道我可以用will
每个变量声明的特征来做到这一点,但我希望有一种不需要注释每个声明的方法。也许有 ::(...) 插值?)
我有一些关于编译指示的相关问题。让我开始这一系列问题的原因是试图确定是否可以禁用某些警告而不用一直到no worries
(我仍然想担心,至少有一点!)。我仍然对那个特定问题的答案感兴趣。
但是考虑这个问题让我意识到我并不真正理解 pragma 是如何工作的。很明显,至少一些 pragma 带有参数(例如,use isms<Perl5>
)。但它们似乎不是函数。它们在整体 MOP 中处于什么位置?它们有点像 Traits 吗?还是包裹?有没有办法反省他们?查看当前有效的编译指示?
编译指示是内置于语言中的,还是用户可以添加的内容?在编写库时,我希望有一些错误/警告,用户可以选择使用编译指示禁用这些错误/警告——这可能吗,或者它们是否仅限于在编译器中使用?如果我可以创建我的 pragma,除了 pragma 更简洁的外观之外,使用 pragma 设置某些内容与使用动态变量设置内容之间是否存在实际差异?就此而言,我们如何决定应该使用 pragma 还是变量设置哪些语言特征(例如,为什么$*TOLERANCE
不是 pragma)?
基本上,我会对您可以提供或指向我的任何有关编译指示的信息感兴趣 - 尽管我的具体问题仍然是我是否可以有选择地关闭某些警告。
以下代码尝试对一个消息做出反应Supply
,然后根据某些消息的内容改变主意并对来自不同的消息作出反应Supply
。它试图提供与Supply.migrate类似的行为,但有更多的控制。
my $c1 = Supplier.new;\nmy $c2 = Supplier.new;\n\nmy $s = supply {\n my $currently-listening-to = $c1.Supply;\n my $other-var = \'foo\';\n whenever $currently-listening-to {\n say "got: $_";\n if .starts-with(\'3\') {\n say "listening to something new";\n $currently-listening-to = $c2.Supply;\n $other-var = \'bar\';\n say $other-var;\n }\n }\n}\n\n$s.tap;\n\nfor ^7 {\n $c1.emit: "$_ from \\$c1";\n $c2.emit: "$_ from \\$c2";\n}\nsleep 10;\n
Run Code Online (Sandbox Code Playgroud)\n如果我正确理解块的语义supply
(非常值得怀疑!),则该块应该对块内声明的任何变量具有独占且可变的访问权限supply
。因此,我希望从 中获取前 4 个值$c1
,然后切换到$c2
. 然而,事实并非如此。这是输出:
ot: 0 from …
Run Code Online (Sandbox Code Playgroud) 2011 年优秀的 Raku Advent of Raku 后元编程:什么、为什么和如何提供了一些使用EXPORTHOW
创建行为类似的声明器的清晰示例class
。这是第一个:
my class SingleInheritanceClassHOW
is Metamodel::ClassHOW
{
method add_parent(Mu $obj, Mu $parent) {
if +self.parents($obj, :local) > 0 {
die "Multiple inheritance is forbidden!";
}
callsame;
}
}
my module EXPORTHOW { }
EXPORTHOW.WHO.<class> = SingleInheritanceClassHOW;
Run Code Online (Sandbox Code Playgroud)
有没有办法对声明器执行类似的操作sub
(即允许用户提供签名和块,而不是允许用户提供属性和方法)?a 的元类Sub
是ClassHOW
,所以看起来类似的东西应该是可能的,但我没有看到这样做的方法。
Raku 提供了许多异常类型,在概念层面上,它们互为子类型。例如,从X::Bind::Slice
概念上讲,是 的子类别X::Bind
。但在对象层次结构级别,X::Bind::Slice
不是Rakudo \xe2\x80\x93 中的子类型,X::Bind
它直接继承自Exception
. 对于许多例外,看起来像超类型的东西甚至不是Exception
; 例如,X::Method
是一个Package
。
另一方面,X::IO
是Role
由各种异常完成的X::IO::*
;因此X::IO::Copy ~~ X::IO
返回True
(不像,说,X::Bind::Slice ~~ X::Bind
)。
Rakudo 中实现的各种类型关系是否有特殊原因?(我说“Rakudo”是因为我不知道任何涵盖这些关系的规范)。
\n更实际的是,对于我自己的异常类型来说,哪种类型层次结构是可取的?我目前的做法是拥有一个基本MyModule::X
类型,其中包含不同类别错误的子类型,而这些子类型又包含特定错误的子类型。(这种方法允许针对错误类别进行智能匹配,这很方便)。但这与我在 Rakudo 中看到的任何方法都非常不同。
我是否缺少一个拥有扁平X::*
层次结构的充分理由?或者,或者,让“例外类别”成为角色而不是类型X::IO
?