class Code is Any does Callable {}

Code 是 Raku 中所有代码对象的最终基类。它公开了所有代码对象都具有的功能。虽然 thunk 直接属于 Code 类型,但大多数代码对象(例如来自块、子例程或方法的代码对象)将属于 Code 的某个子类。

方法§

方法 ACCEPTS§

multi method ACCEPTS(Code:D: Mu $topic)

通常调用代码对象并将$topic作为参数传递。但是,当在不接受参数的代码对象上调用时,代码对象将不带参数调用,并且$topic将被丢弃。调用结果将被返回。

方法 arity§

method arity(Code:D: --> Int:D)

返回调用代码对象时必须传递的最小位置参数数量。代码对象中的任何可选或贪婪参数Signature都不会贡献,命名参数也不会贡献。

sub argless() { }
sub args($a$b?{ }
sub slurpy($a$b*@c{ }
say &argless.arity;             # OUTPUT: «0␤» 
say &args.arity;                # OUTPUT: «1␤» 
say &slurpy.arity;              # OUTPUT: «2␤»

方法 assuming§

method assuming(Callable:D $self: |primers)

返回一个新的Callable,它已被预先填充传递给assuming的参数。换句话说,新函数实现与原始函数相同的行为,但已将传递给.assuming的值绑定到相应的参数。

my sub slow($n){ my $i = 0$i++ while $i < $n$i };
 
# takes only one parameter and as such wont forward $n 
sub bench(&c){ cnow - ENTER now };
 
say &slow.assuming(10000000).&bench# OUTPUT: «(10000000 7.5508834)␤»

对于 arity 大于 1 的子程序,可以使用Whatever * 来表示所有未“假设”的位置参数。

sub first-and-last ( $first$last ) {
    say "Name is $first $last";
}
 
my &surname-smith = &first-and-last.assuming*'Smith' );
 
&surname-smith.'Joe' ); # OUTPUT: «Name is Joe Smith␤»

您可以处理任何组合的假设和未假设的位置参数

sub longer-names ( $first$middle$last$suffix ) {
    say "Name is $first $middle $last $suffix";
}
 
my &surname-public = &longer-names.assuming**'Public'* );
 
&surname-public.'Joe''Q.''Jr.'); # OUTPUT: «Name is Joe Q. Public Jr.␤» 

命名参数也可以被假设

sub foo { say "$^a $^b $:foo $:bar" }
&foo.assuming(13:42foo)(24:72bar); # OUTPUT: «13 24 42 72␤»

您可以在所有类型的Callable上使用.assuming,包括方法

# We use a Whatever star for the invocant: 
my &comber = Str.^lookup('comb').assuming: *, /\w+/;
say comber 'Perl is awesome! Python is great! And PHP is OK too';
# OUTPUT: «(Perl Python PHP)␤» 
 
my &learner = {
    "It took me $:months months to learn $^lang"
}.assuming: 'Raku';
say learner :6months;  # OUTPUT: «It took me 6 months to learn Raku␤»

方法 count§

method count(Code:D: --> Real:D)

返回调用代码对象时可以传递的最大位置参数数量。对于可以接受任意数量位置参数的代码对象(即它们具有贪婪参数),count 将返回Inf。命名参数不会贡献。

sub argless() { }
sub args($a$b?{ }
sub slurpy($a$b*@c{ }
say &argless.count;             # OUTPUT: «0␤» 
say &args.count;                # OUTPUT: «2␤» 
say &slurpy.count;              # OUTPUT: «Inf␤»

方法 of§

method of(Code:D: --> Mu)

返回Code返回类型约束

say -> () --> Int {}.of# OUTPUT: «(Int)␤»

方法 signature§

multi method signature(Code:D: --> Signature:D)

返回此代码对象的Signature 对象,它描述了其参数。

sub a(Int $oneStr $two{};
say &a.signature# OUTPUT: «(Int $one, Str $two)␤»

方法 cando§

method cando(Capture $c)

返回可以使用给定Capture调用的候选者列表。由于Code对象没有任何多重调度,因此这将返回一个包含该对象的列表,或者返回一个空列表。

my $single = \'a';         # a single argument Capture 
my $plural = \('a'42);   # a two argument Capture 
my &block = { say $^a };   # a Block object, that is a subclass of Code, taking one argument 
say &block.cando($single); # OUTPUT: «(-> $a { #`(Block|94212856419136) ... })␤» 
say &block.cando($plural); # OUTPUT: «()␤»

方法 Str§

multi method Str(Code:D: --> Str:D)

将输出方法名称,但也会产生警告。请改用.raku.gist

sub marine() { }
say ~&marine;
# OUTPUT: «Sub object coerced to string (please use .gist or .raku to do that)␤marine␤» 
say &marine.Str;
# OUTPUT: «Sub object coerced to string (please use .gist or .raku to do that)␤marine␤» 
say &marine.raku# OUTPUT: «sub marine { #`(Sub|94280758332168) ... }␤»

方法 file§

method file(Code:D: --> Str:D)

返回声明代码对象的源文件名。

say &infix:<+>.file;   # OUTPUT: «SETTING::src/core.c/Numeric.rakumod␤»

方法 line§

method line(Code:D: --> Int:D)

返回源代码中代码对象声明开始的行号。

say &infix:<+>.line;   # OUTPUT: «208␤»

如果代码对象是自动生成的(因此在源代码中声明),则line将返回封闭作用域声明开始的行。例如,当在自动生成的访问器方法(由has $.name语法生成)上调用时,line将返回方法所属类的声明开始的行。

例如,如果您有以下源文件

class Food {                # Line 1 
    has $.ingredients;      # Line 2 
                            # Line 3 
    method eat {};          # Line 4 
}                           # Line 5

那么line方法将为您提供以下输出

say Food.^lookup('eat').line;          # OUTPUT: «4␤» 
say Food.^lookup('ingredients').line;  # OUTPUT: «1␤» 

方法 bytecode-size§

method bytecode-size(--> Int:D)

注意:此方法仅在 MoarVM 后端上的 Rakudo 编译器中可用,从 2022.06 版本开始。

返回代码对象在内存中占用的字节数。请注意,如果代码对象实际上是multi,则将报告proto的字节码大小。您可以使用.candidates方法获取每个候选者,然后在它们上调用bytecode-size方法。

say &grep.bytecode-size;              # OUTPUT: «114␤» 
say &grep.cadidates>>.bytecode-size;  # OUTPUT: «424␤258␤»

方法 is-implementation-detail§

method is-implementation-detail(--> False)

注意:此方法在 Rakudo 编译器中从 2020.05 版本开始可用。

如果代码对象用is implementation-detail特征标记,则返回True,否则返回False

类型图§

Code的类型关系
raku-type-graph Code Code Any Any Code->Any Callable Callable Code->Callable Mu Mu Any->Mu WhateverCode WhateverCode WhateverCode->Code Block Block Block->Code Routine Routine Routine->Block Macro Macro Macro->Routine Sub Sub Sub->Routine Method Method Method->Routine Submethod Submethod Submethod->Routine Regex Regex Regex->Method

展开上方的图表