EVAL
ErrorsCollection

EVAL

Synthesised documentation from type/independent-routines type/Cool

From type/independent-routines

See Original text in context

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

This routine executes at runtime a fragment of code, $code, of a given language, $lang, which defaults to Raku.

It coerces Cool $code to Str. If $code is a Blob, it'll be processed using the same encoding as the $lang compiler would: for Raku $lang, uses utf-8; for Perl5, processes using the same rules as Perl.

This works as-is with a literal string parameter. More complex input, such as a variable or string with embedded code, is illegal by default. This can be overridden in any of several ways:

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␤»

In case the MONKEY-SEE-NO-EVAL pragma is not activated, the compiler will complain with a EVAL is a very dangerous function!!! exception. And it is essentially right, since that will run arbitrary code with the same permissions as the program. You should take care of cleaning the code that is going to pass through EVAL if you activate the MONKEY-SEE-NO-EVAL pragma.

Please note that you can interpolate to create routine names using quotation, as can be seen in this example or other ways to interpolate to create identifier names. This only works, however, for already declared functions and other objects and is thus safer to use.

Symbols in the current lexical scope are visible to code in an EVAL.

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

However, since the set of symbols in a lexical scope is immutable after compile time, an EVAL can never introduce symbols into the surrounding scope.

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

Furthermore, the EVAL is evaluated in the current package:

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

And also in the current language, meaning any added syntax is available:

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

An EVAL statement evaluates to the result of the last statement:

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

EVAL is also a gateway for executing code in other languages:

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

You need to have Inline::Perl5 for this to work correctly.

More languages may be supported with additional modules which may be found from the Raku Modules Directory.

If the optional $filename parameter is given, the $?FILE variable is set to its value. Otherwise $?FILE is set to a unique and generated file name.

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

If the optional $check parameter is True, $code is processed by the $lang compiler but is not actually run. For Raku, BEGIN, and CHECK blocks are run. The EVAL routine then returns Nil if compilation was successful, otherwise an exception is thrown.

From type/Cool

See Original text in context

method EVAL(*%_)

It calls the subroutine form with the invocant as the first argument, $code, passing along named args, if any.