is Any does Callable
Code
是 Raku 中所有代码对象的最终基类。它公开了所有代码对象都具有的功能。虽然 thunk 直接属于 Code
类型,但大多数代码对象(例如来自块、子例程或方法的代码对象)将属于 Code
的某个子类。
方法§
方法 ACCEPTS§
multi method ACCEPTS(Code: Mu )
通常调用代码对象并将$topic
作为参数传递。但是,当在不接受参数的代码对象上调用时,代码对象将不带参数调用,并且$topic
将被丢弃。调用结果将被返回。
方法 arity§
method arity(Code: --> Int)
返回调用代码对象时必须传递的最小位置参数数量。代码对象中的任何可选或贪婪参数Signature
都不会贡献,命名参数也不会贡献。
sub argless()sub args(, ?)sub slurpy(, , *)say .arity; # OUTPUT: «0»say .arity; # OUTPUT: «1»say .arity; # OUTPUT: «2»
方法 assuming§
method assuming(Callable : |primers)
返回一个新的Callable
,它已被预先填充传递给assuming
的参数。换句话说,新函数实现与原始函数相同的行为,但已将传递给.assuming
的值绑定到相应的参数。
my sub slow();# takes only one parameter and as such wont forward $nsub bench();say .assuming(10000000).; # OUTPUT: «(10000000 7.5508834)»
对于 arity 大于 1 的子程序,可以使用Whatever
*
来表示所有未“假设”的位置参数。
sub first-and-last ( , )my = .assuming( *, 'Smith' );.( 'Joe' ); # OUTPUT: «Name is Joe Smith»
您可以处理任何组合的假设和未假设的位置参数
sub longer-names ( , , , )my = .assuming( *, *, 'Public', * );.( 'Joe', 'Q.', 'Jr.'); # OUTPUT: «Name is Joe Q. Public Jr.»
命名参数也可以被假设
sub foo.assuming(13, :42foo)(24, :72bar); # OUTPUT: «13 24 42 72»
您可以在所有类型的Callable上使用.assuming
,包括方法和块
# We use a Whatever star for the invocant:my = Str.^lookup('comb').assuming: *, /P \w+/;say comber 'Perl is awesome! Python is great! And PHP is OK too';# OUTPUT: «(Perl Python PHP)»my =.assuming: 'Raku';say learner :6months; # OUTPUT: «It took me 6 months to learn Raku»
方法 count§
method count(Code: --> Real)
返回调用代码对象时可以传递的最大位置参数数量。对于可以接受任意数量位置参数的代码对象(即它们具有贪婪参数),count
将返回Inf
。命名参数不会贡献。
sub argless()sub args(, ?)sub slurpy(, , *)say .count; # OUTPUT: «0»say .count; # OUTPUT: «2»say .count; # OUTPUT: «Inf»
方法 of§
method of(Code: --> Mu)
返回Code
的返回类型约束
say -> () --> Int .of; # OUTPUT: «(Int)»
方法 signature§
multi method signature(Code: --> Signature)
返回此代码对象的Signature
对象,它描述了其参数。
sub a(Int , Str ) ;say .signature; # OUTPUT: «(Int $one, Str $two)»
方法 cando§
method cando(Capture )
返回可以使用给定Capture
调用的候选者列表。由于Code
对象没有任何多重调度,因此这将返回一个包含该对象的列表,或者返回一个空列表。
my = \'a'; # a single argument Capturemy = \('a', 42); # a two argument Capturemy = ; # a Block object, that is a subclass of Code, taking one argumentsay .cando(); # OUTPUT: «(-> $a { #`(Block|94212856419136) ... })»say .cando(); # OUTPUT: «()»
方法 Str§
multi method Str(Code: --> Str)
将输出方法名称,但也会产生警告。请改用.raku
或.gist
。
sub marine()say ~;# OUTPUT: «Sub object coerced to string (please use .gist or .raku to do that)marine»say .Str;# OUTPUT: «Sub object coerced to string (please use .gist or .raku to do that)marine»say .raku; # OUTPUT: «sub marine { #`(Sub|94280758332168) ... }»
方法 file§
method file(Code: --> Str)
返回声明代码对象的源文件名。
say :<+>.file; # OUTPUT: «SETTING::src/core.c/Numeric.rakumod»
方法 line§
method line(Code: --> Int)
返回源代码中代码对象声明开始的行号。
say :<+>.line; # OUTPUT: «208»
如果代码对象是自动生成的(因此未在源代码中声明),则line
将返回封闭作用域声明开始的行。例如,当在自动生成的访问器方法(由has $.name
语法生成)上调用时,line
将返回方法所属类的声明开始的行。
例如,如果您有以下源文件
# Line 5
那么line
方法将为您提供以下输出
say Food.^lookup('eat').line; # OUTPUT: «4»say Food.^lookup('ingredients').line; # OUTPUT: «1»
方法 bytecode-size§
method bytecode-size(--> Int)
注意:此方法仅在 MoarVM 后端上的 Rakudo 编译器中可用,从 2022.06 版本开始。
返回代码对象在内存中占用的字节数。请注意,如果代码对象实际上是multi
,则将报告proto
的字节码大小。您可以使用.candidates
方法获取每个候选者,然后在它们上调用bytecode-size
方法。
say .bytecode-size; # OUTPUT: «114»say .cadidates>>.bytecode-size; # OUTPUT: «424258»
方法 is-implementation-detail§
method is-implementation-detail(--> False)
注意:此方法在 Rakudo 编译器中从 2020.05 版本开始可用。
如果代码对象用is implementation-detail
特征标记,则返回True
,否则返回False
。