在 Cool 中§
有关方法 EVAL,请参阅上下文中的主要文档
method EVAL(*)
它使用调用者作为第一个参数、$code
,传递命名参数(如果有)来调用子例程形式。
在独立例程中§
有关例程 EVAL,请参阅上下文中的主要文档
proto EVAL( where Blob|Cool|Callable, Str() : = 'Raku',PseudoStash :, Str() :, Bool() :, *)
multi EVAL(, Str : where ,PseudoStash :, Str() :, :)
此例程在运行时执行给定语言的代码片段 $code
,$lang
,其默认为 Raku
。
它将Cool
$code
强制转换为Str
。如果 $code
是Blob
,它将使用与 $lang
编译器相同的编码进行处理:对于 Raku
$lang
,使用 utf-8
;对于 Perl5
,使用与 Perl 相同的规则进行处理。
这适用于带有文字字符串参数的情况。更复杂的输入,例如包含嵌入代码的变量或字符串,默认情况下是非法的。可以通过多种方式覆盖此项
use MONKEY-SEE-NO-EVAL; # Or...use MONKEY; # shortcut that turns on all MONKEY pragmasuse Test;my = 0;my = 10;my Str = '$init += ' ~ ; # contains a Str object with value '$init += 10'# any of the above allows:EVAL ;EVAL ;say ; # OUTPUT: «20»
如果未激活 MONKEY-SEE-NO-EVAL
编译指示,编译器将抱怨 EVAL is a very dangerous function!!!
异常。从本质上讲,这是正确的,因为这将以与程序相同的权限运行任意代码。如果您激活 MONKEY-SEE-NO-EVAL
编译指示,则应注意清除将通过 EVAL 传递的代码。
请注意,您可以使用引号插值来创建例程名称,如此示例或插值以创建标识符名称的其他方式中所示。但是,这只适用于已声明的函数和其他对象,因此使用起来更安全。
当前词法范围内的符号对 EVAL
中的代码可见。
my = 42;EVAL 'say $answer;'; # OUTPUT: «42»
但是,由于词法范围内的符号集在编译后不可变,因此 EVAL
永远不会将符号引入周围范围。
EVAL 'my $lives = 9'; say ; # error, $lives not declared
此外,EVAL
在当前包中求值
say ::answer; # OUTPUT: «42»
也以当前语言求值,这意味着任何添加的语法都可用
sub infix:<mean>(*) is assoc<list>EVAL 'say 2 mean 6 mean 4'; # OUTPUT: «4»
EVAL
语句求值为最后一条语句的结果
sub infix:<mean>(*) is assoc<list>say EVAL 'say 1; 2 mean 6 mean 4'; # OUTPUT: «14»
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
编译器处理,但实际上不会运行。对于 Raku
,BEGIN
和CHECK
块将运行。如果编译成功,则 EVAL
例程返回Nil
,否则将抛出一个异常。