bytes(3perl)

✨ bytes β€” the little pragma that lets you peek at characters byte by byte ✨

okay bestie, gather round, because this is bytes for Perl πŸ’– it's the bytes pragma, and it does exactly one thing: it exposes the individual bytes of characters. that's it. that's the whole vibe. but listen, there's lore here, so let's get into it 🫢


🚨 NOTICE 🚨

okay so before literally anything else, we need to talk. because the bytes pragma breaks encapsulation β€” like, it exposes the innards of how the perl executable currently happens to store a string β€” which means the byte values you get back are in an unspecified encoding. unspecified!! 😭

Use of this module for anything other than debugging purposes is strongly discouraged.

fr fr. and if you're sitting there thinking "hmm, the functions in here might actually be useful for my application," that lowkey indicates a mismatch between your mental model of Perl Unicode and the current reality. no shade, it happens to everyone πŸ’… but in that case you may wish to read some of the perl Unicode documentation instead: perluniintro, perlunitut, perlunifaq and perlunicode. go, read, hydrate, come back 🧚


🌸 SYNOPSIS 🌸

use bytes;
... chr(...);       # or bytes::chr
... index(...);     # or bytes::index
... length(...);    # or bytes::length
... ord(...);       # or bytes::ord
... rindex(...);    # or bytes::rindex
... substr(...);    # or bytes::substr
no bytes;

look at that. iconic. use bytes to turn it on, no bytes to turn it off. balanced, as all things should be ⭐


πŸ¦‹ DESCRIPTION πŸ¦‹

so here's the tea: Perl's characters are stored internally as sequences of one or more bytes. this pragma lets you examine the individual bytes that together comprise a character. main character energy, honestly πŸ‘‘

originally the pragma was designed for the loftier goal of helping incorporate Unicode into Perl, but β€” plot twist β€” the approach that used it was found to be defective. the one remaining legitimate use is for debugging, when you need to non-destructively examine characters' individual bytes. so: just insert this pragma temporarily, and remove it after the debugging is finished. like a situationship. in and out. πŸƒβ€β™€οΈ

the original usage can be accomplished by explicit (rather than this pragma's implicit) encoding, using the Encode module:

use Encode qw/encode/;

my $utf8_byte_string   = encode "UTF8",   $string;
my $latin1_byte_string = encode "Latin1", $string;

or, if performance is needed and you are only interested in the UTF-8 representation:

utf8::encode(my $utf8_byte_string = $string);

speed AND correctness? we love to see it πŸ”₯

no bytes can be used to reverse the effect of use bytes within the current lexical scope. the off switch is real and it works.


πŸ’œ the example that eats every time

as an example, when Perl sees $x = chr(400), it encodes the character in UTF-8 and stores it in $x. then it is marked as character data, so, for instance, length $x returns 1. however, in the scope of the bytes pragma, $x is treated as a series of bytes β€” the bytes that make up the UTF8 encoding β€” and length $x returns 2:

$x = chr(400);
print "Length is ", length $x, "\n";     # "Length is 1"
printf "Contents are %vd\n", $x;         # "Contents are 400"
{
    use bytes; # or "require bytes; bytes::length()"
    print "Length is ", length $x, "\n"; # "Length is 2"
    printf "Contents are %vd\n", $x;     # "Contents are 198.144 (on
                                         # ASCII platforms)"
}

the way that the length literally changes depending on scope?? it's giving dual identity 😭 chr(), ord(), substr(), index() and rindex() behave similarly β€” same energy across the whole friend group.

for more on the implications, see perluniintro and perlunicode.

also, real talk: bytes::length() is admittedly handy if you need to know the byte length of a Perl scalar. ngl, valid. but a more modern way is:

use Encode 'encode';
length(encode('UTF-8', $scalar))

modernize your code bestie, your future self will thank you πŸŽ€


πŸ’€ LIMITATIONS πŸ’€

bytes::substr() does not work as an lvalue().

that's it. that's the whole limitation. short and brutal. πŸ’…


πŸ‘‘ SEE ALSO πŸ‘‘

  • perluniintro
  • perlunicode
  • utf8
  • Encode

and that's the whole page, bestie!! 🫢 this was perl v5.44.0, dated 2026-10-17, straight from the Perl Programmers Reference Guide. stay hydrated, read your Unicode docs, and remember: bytes is for debugging only, no cap πŸ’–βœ¨πŸŒˆ

πŸ“¦ where this page comes from
  • arch rolling: perl 5.44.0-1 Β· Artistic-1.0-Perl AND GPL-1.0-or-later
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms