CodeUnit
NAME
CodeUnit - provide a unit for execution of code
SYNOPSIS
use CodeUnit;
my $cu = CodeUnit.new;
$cu.eval('my $a = 42');
$cu.eval('say $a'); # 42
$cu.eval('say $b');
with $cu.exception {
note .message.chomp; # Variable '$b' is not declared...
$cu.exception = Nil;
}
DESCRIPTION
The CodeUnit distribution provides an interface to a compiler
context that allows code to be evaluated by given strings, while
maintaining context between states.
As such it provides one of the underlying functionalities of a REPL (Read Evaluate Print Loop), but could be used by itself for a multitude of uses.
METHODS
new
my $cu1 = CodeUnit.new;
# use current context
my $context = context; # must be separate call
my $cu2 = CodeUnit.new(:$context);
# don't show warnings
my $cu3 = CodeUnit.new(:keep-warnings);
$cu3.eval(q/my $x; $x + 1/); # no output
.note for $cu3.warnings.map(*.Str.lines.head); # show without backtrace
# start with grammar including any mixins
my $cu4 = CodeUnit.new(:lang(BEGIN $*LANG));
The new method instantiates a CodeUnit object. It takes the
following named arguments:
:context
Optional. The :context named argument can be specified with a value
returned by the context subroutine. If not specified, will
assume a fresh context without any outer / caller lexicals visible.
Used value available with the .context method.
:keep-warnings
Optional. If specified with a true value, will cause any warnings to
be stored in the CodeUnit object rather than being shown on STDERR.
The warnings (as CX::Warn objects including their full stack-traces)
are accessible with the warnings method (which will also reset any
warnings collected so far).
:lang
Optional. Specified which grammar / action class to be used. Defaults
to the standard Raku grammar and action class. If specified, this is
usually BEGIN $*LANG;
:compiler
Optional. The :compiler named argument can be specified to indicate
the low level compiler object that sould be used. Can be specified as
a string, in which case it will be used as an argument to the
nqp::getcomp function to obtain the low level compiler object.
Defaults to "Raku".
Used value available with the .compiler method.
:multi-line-ok
Optional, Boolean. Indicate whether it is ok to interprete multiple
lines of input as a single statement to evaluate. Defaults to
True unless the RAKUDO_DISABLE_MULTILINE environment variable
has been specified with a true value.
Used value available with the .multi-line-ok method, and can be
used as a left-value to change.
:grammar
Optional. Specifies the grammar to be used initially. Defaults
to the standard Raku grammar, or to what has been specified with :lang.
Value available with the .grammar method.
:actions
Optional. Specifies the action class to be used. Defaults to the
standard Raku actions, or to what the .actions method returns on what
is specified with :lang.
eval
$cu.eval('my $a = 42');
$cu.eval('say $a'); # 42
The eval method evaluates the given string with Raku code within
the context of the code unit, and returns the result of the evaluation.
reset
$cu.reset;
The reset method resets the context of the code unit to its initial
state as (implicitely) specified with .new.
compiler-version
say $cu.compiler-version;
# Welcome to Rakudo⢠v2025.01.
# Implementing the RakuĀ® Programming Language v6.d.
# Built on MoarVM version 2025.01.
The compiler-version method returns the compiler version information,
which is typically shown when starting a REPL.
context-completions
.say for $cu.context-completions;
The context-completions method returns an unsorted list of context
completion candidates found in the context of the code unit, which are
typically used to provide completions in a REPL (hence the name).
state
The state method returns one of the Status enums to indicate
the result of the last call to .eval. It can also be used as a
left-value to set the state (usually to OK).
exception
with $cu.exception {
note .message.chomp; # Variable '$b' is not declared...
$cu.exception = Nil;
}
The exception method returns the Exception object if anything
went wrong in the .eval call. Note that this can also be the
case even if the state is OK. Can also be used as a left-value
to (re)set.
warnings
my $cu = CodeUnit.new(:keep-warnings);
$cu.eval(q/my $x; $x + 1/); # no output
.note for $cu.warnings.map(*.Str.lines.head);
# Use of uninitialized value $x of type Any in numeric context
ENUMS
Status
The Status enum is exported: it is used by the state method to
indicate the state of the last call to .eval. It provides the
following states:
OK (0) - evalution ok
MORE-INPUT (1) - string looks like incomplete code
CONTROL (2) - some kind of control statement was executed
SUBROUTINES
context
my $context = context;
my $cu = CodeUnit.new(:$context);
The context subroutine returns a context object that can be used to
initialize the context of a code unit with.
CAVEATS
"Invisible" variables
By default, Raku does a lot of compile-time as well as run-time
optimizations. This may lead to lexical variables being optimized
away, and thus become "invisible" to introspection. If that appears
to be the case, then starting Raku with --optimize=off may make
these "invisble" variables visible.
Each call is a scope
Because each call introduces its own scope, certain side-effects of this
scoping behaviour may produce unexpected results and/or errors. For
example: my $a = 42, followed by say $a, is really:
my $a = 42;
{
say $a;
}
This works because the lexical variable $a is visible from the scope
that has the say.
Another example which you might expect to give at least a warning, but
doesn't: my $a = 42; followed by my $a = 666, which would normally
produce a worry: "Redeclaration of symbol '$a'", but doesn't here because
they are different scopes:
my $a = 42;
{
my $a = 666;
}
As you can see, the second $a shadows the first $a, and is not a worry
as such.
Future versions of CodeUnit may be able to work around this scoping
behaviour.
AUTHOR
Elizabeth Mattijsen <[email protected]>
Source can be located at: https://codeberg.org/lizmat/CodeUnit . Comments and Pull Requests are welcome.
If you like this module, or what I'm doing more generally, committing to a small sponsorship would mean a great deal to me!
COPYRIGHT AND LICENSE
Copyright 2025, 2026 Elizabeth Mattijsen
This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.
# vim: expandtab shiftwidth=4