evalbytes#
Compile and run a string of Perl source, forcing the source to be interpreted as bytes rather than characters.
evalbytes is the byte-oriented twin of string eval. It
takes an EXPR (or $_ when EXPR is omitted), treats the
string as a raw byte stream, and parses it as Perl source. The parse
is insulated from the caller’s use utf8 pragma: whatever encoding
rules the string itself declares win. Reach for it when the code you
are about to compile was read from disk, the wire, or a build step,
and you need the parser to see exactly the bytes you handed it.
Synopsis#
evalbytes EXPR
evalbytes
CORE::evalbytes EXPR # when the feature is not enabled
What you get back#
In scalar context, the value of the last expression evaluated; in
list context, a list. On a compile or run-time error, undef (or
an empty list) and $@ is set to the error message; $@ is
the empty string on success. Return shape matches string
eval exactly — the only difference is how the source text
itself is decoded.
my $result = evalbytes $source;
die $@ if $@;
How it differs from string eval#
Two concrete behaviours distinguish evalbytes from
eval EXPR:
The source is parsed as bytes. Every octet in the string is a separate input character to the lexer, regardless of whether the string is internally marked as
utf8. A multi-byte UTF-8 sequence in the source shows up to the parser as the individual bytes, not as the decoded code point.Code points above 255 are a hard error. If the string contains any character whose ordinal exceeds
0xFF, it cannot be a byte stream and the compile fails withWide character in evalstored in$@. Downgrade withutf8::encodefirst if the source currently holds decoded text.
use utf8 and no utf8 inside the evaluated code have their
usual effect: the pragma switches on once the parser reaches it and
affects the remainder of that compilation. It is the source’s outer
framing that is fixed to bytes, not what the source itself declares.
Enabling the name without CORE::#
evalbytes is feature-gated. To call it as a bareword:
use feature 'evalbytes';
A use v5.16 (or higher) declaration enables the evalbytes feature
automatically, along with the rest of the :5.16 feature bundle.
Without either, the unqualified name is not recognised and you must
write CORE::evalbytes explicitly — useful inside generated code or
one-liners that do not carry a version declaration.
use v5.16;
my $n = evalbytes '1 + 2'; # 3
# no feature, no version bundle:
my $n = CORE::evalbytes '1 + 2'; # 3
Global state it touches#
$@— cleared before the compile, then set to the error message on failure or the empty string on success. Same contract aseval.$_— read as the source text whenEXPRis omitted.
Source filters activated inside the evaluated code apply to the
code itself, exactly as they would inside a string eval. The
filter sees the same bytes the parser sees.
Examples#
Evaluate a literal byte string — no surprises, no encoding choices to make:
use feature 'evalbytes';
my $n = evalbytes 'my $x = 40; $x + 2'; # 42
Evaluate source read from a file that is known to be UTF-8 encoded but whose declared pragma inside the source is what should govern parsing:
use feature 'evalbytes';
open my $fh, '<:raw', 'script.pl' or die $!;
my $src = do { local $/; <$fh> };
my @values = evalbytes $src;
die "compile failed: $@" if $@;
Reading with :raw keeps $src a byte string. evalbytes then
feeds those bytes to the parser verbatim; a use utf8; line at the
top of the script will do its own work once the parser reaches it.
Compare with string eval when the caller has use utf8:
use utf8;
use feature 'evalbytes';
my $src = "length('caf\xc3\xa9')"; # bytes for 'café' in UTF-8
print eval $src; # 3 (characters: c, a, f, é)
print "\n";
print evalbytes $src; # 5 (bytes: c, a, f, 0xC3, 0xA9)
print "\n";
Under use utf8 the caller’s own literal "length('caf\xc3\xa9')"
is a character string to eval, so length inside the
evaluated code sees one é character. evalbytes forces the same
source to be parsed as the byte sequence c a f 0xC3 0xA9, so
length reports the byte count.
Catching a wide-character error:
use feature 'evalbytes';
my $src = "print \x{2603}"; # contains U+2603 SNOWMAN
evalbytes $src;
warn "rejected: $@" if $@; # "Wide character in eval ..."
Omitting EXPR — source comes from $_:
use feature 'evalbytes';
for ('1+1', '2*3', '10-7') {
my $r = evalbytes;
print "$_ = $r\n";
}
Edge cases#
Wide character in source: any code point above
0xFFaborts the compile and leavesWide character in evalin$@. Runutf8::encodeon the source (or read the file in:raw) before calling.use utf8is local to the evaluated code. It affects string literals and identifiers inside the evaluated text once the parser reaches the pragma line. It does not change howevalbytesframes the outer source — that framing is always “bytes”.Feature not enabled: without
use feature 'evalbytes'and without ause v5.16+bundle, the bareword is unrecognised. WriteCORE::evalbytesto bypass the feature gate.evalbyteswith no argument and$_undef: compiles an empty string, which succeeds and returnsundefin scalar context, the empty list in list context, with$@empty.Source filters inside the evaluated code see the byte stream. A filter that expects decoded characters will misbehave; write filters for
evalbytesin terms of bytes.Lexicals and package state: same rules as string
eval. The evaluated code shares the caller’s current package and sees the caller’s in-scope lexicals; its ownmyvariables vanish when the eval finishes.dieinsideevalbytes: caught the same way as foreval. The thrown value lands in$@; execution continues after theevalbytescall.
Differences from upstream#
Fully compatible with upstream Perl 5.42.
See also#
eval— the character-mode counterpart; parsesEXPRaccording to the caller’s Unicode framing, souse utf8in the caller changes how the source is interpreteddie— throw an exception from within evaluated code; sets$@just like any other run-time errordo— compile and run a file; takes its source from disk rather than a string, and is not affected by the caller’sutf8framingrequire— load and compile a file once; the standard tool when the source lives on disk and should only run on first referenceutf8— the pragma controlling character vs byte semantics of string literals;evalbytesexists precisely to pin the outer framing to bytes regardless of this pragma$@— the error slot populated onevalbytesfailure, cleared on success