在 Cool 中§

有关方法 EVAL,请参阅上下文中的主要文档

method EVAL(*%_)

它使用调用者作为第一个参数、$code,传递命名参数(如果有)来调用子例程形式

在独立例程中§

有关例程 EVAL,请参阅上下文中的主要文档

proto EVAL($code where Blob|Cool|CallableStr() :$lang = 'Raku',
                PseudoStash :$contextStr() :$filenameBool() :$check*%_)
multi EVAL($codeStr :$lang where { ($lang // ''eq 'Perl5' },
                PseudoStash :$contextStr() :$filename:$check)

此例程在运行时执行给定语言的代码片段 $code$lang,其默认为 Raku

它将Cool $code强制转换为Str。如果 $codeBlob,它将使用与 $lang 编译器相同的编码进行处理:对于 Raku $lang,使用 utf-8;对于 Perl5,使用与 Perl 相同的规则进行处理。

这适用于带有文字字符串参数的情况。更复杂的输入,例如包含嵌入代码的变量或字符串,默认情况下是非法的。可以通过多种方式覆盖此项

use MONKEY-SEE-NO-EVAL# Or... 
use MONKEY;             # shortcut that turns on all MONKEY pragmas 
use Test;
 
my $init = 0;
my $diff = 10;
my Str $changer = '$init += ' ~ $diff# contains a Str object with value '$init += 10' 
# any of the above allows: 
EVAL $changer;
EVAL $changer;
say $init;                         # OUTPUT: «20␤»

如果未激活 MONKEY-SEE-NO-EVAL 编译指示,编译器将抱怨 EVAL is a very dangerous function!!! 异常。从本质上讲,这是正确的,因为这将以与程序相同的权限运行任意代码。如果您激活 MONKEY-SEE-NO-EVAL 编译指示,则应注意清除将通过 EVAL 传递的代码。

请注意,您可以使用引号插值来创建例程名称,如此示例插值以创建标识符名称的其他方式中所示。但是,这只适用于已声明的函数和其他对象,因此使用起来更安全。

当前词法范围内的符号对 EVAL 中的代码可见。

my $answer = 42;
EVAL 'say $answer;';    # OUTPUT: «42␤»

但是,由于词法范围内的符号集在编译后不可变,因此 EVAL 永远不会将符号引入周围范围。

EVAL 'my $lives = 9'say $lives;   # error, $lives not declared 

此外,EVAL 在当前包中求值

module M {
    EVAL 'our $answer = 42'
}
say $M::answer;         # OUTPUT: «42␤»

也以当前语言求值,这意味着任何添加的语法都可用

sub infix:<mean>(*@ais assoc<list> {
    @a.sum / @a.elems
}
EVAL 'say 2 mean 6 mean 4';     # OUTPUT: «4␤»

EVAL 语句求值为最后一条语句的结果

sub infix:<mean>(*@ais assoc<list> {
    @a.sum / @a.elems
}
say EVAL 'say 1; 2 mean 6 mean 4';         # OUTPUT: «1␤4␤» 

EVAL 也是执行其他语言中代码的网关

EVAL "use v5.20; say 'Hello from perl!'":lang<Perl5>;

您需要Inline::Perl5才能正确工作。

其他语言可能会得到其他模块的支持,这些模块可以在Raku 模块目录中找到。

如果给出了可选的 $filename 参数,则$?FILE变量将被设置为其值。否则,$?FILE 将被设置为唯一且生成的文件名。

use MONKEY-SEE-NO-EVAL;
EVAL 'say $?FILE';                              # OUTPUT: «/tmp/EVAL_0␤» 
EVAL 'say $?FILE'filename => '/my-eval-code'# OUTPUT: «/my-eval-code␤» 

如果可选的 $check 参数为 True,则 $code 将由 $lang 编译器处理,但实际上不会运行。对于 RakuBEGINCHECK块将运行。如果编译成功,则 EVAL 例程返回Nil,否则将抛出一个异常。