Perl 5.28 makes bitwise intent explicit
Perl 5.28 stabilizes separate numeric and string bitwise operations, while improving in-place editing and several other familiar constructs.
A bitwise expression in Perl can depend on whether its operands have numeric or string values. The operator documentation shipped with Perl 5.28 illustrates the difference with 150 and 105. Numeric OR yields 255, while OR between the strings containing those digits yields the string 155 on ASCII systems. The expression can look similar while describing a different computation.
Perl 5.28 stabilizes a feature that lets the operator spelling decide. With bitwise enabled, the ordinary bitwise operators operate numerically, while dotted forms operate on strings. The release notes identify this feature as introduced experimentally in Perl 5.22. The release history dates the stable 5.28.0 release to June 22.
I value Perl for concise text transformations, but an expression still needs to communicate its intended operation. The stable feature improves that communication where values can plausibly represent either numbers or bitstrings. A reader can identify the requested interpretation from the operator without reconstructing how both operands acquired their values.
The operator chooses the interpretation
The feature remains opt-in because its numeric operators have the same spellings as the older operators. Loading a newer interpreter alone cannot silently change the interpretation of every existing expression. Code enables the feature explicitly or through the version declaration that includes it.
use v5.28;
use strict;
use warnings;
my $numeric = "150" | "105";
my $string = "150" |. "105";
say $numeric; # 255
say $string; # 155 on ASCII systems
The dotted form is a string operation even when an operand begins as a number. The ordinary form is numeric even when both operands contain strings of digits. Examples in the documentation cover each combination of number and string operands, including the cases where both operands begin with the same representation. This is a change in how the operation selects its interpretation, with conversion following that selection.
An existing program can also use use feature "bitwise" without selecting the full version feature bundle. The release notes say -E enables the feature as well. Existing suppression of the experimental::bitwise warning continues to work, but enabling the feature no longer emits that experimental warning in this release.
This matters for compatibility in two directions. Code that relies on the older operand-sensitive behaviour should not acquire a new meaning simply by running on 5.28. Code that opts into the stable feature receives an explicit numeric meaning for the ordinary operators. The feature boundary makes those choices coexist within the language.
The assignment variants follow the same distinction. Under the feature, |= is numeric and |.= is string-oriented, with corresponding forms for AND and XOR. An update to an existing accumulator can therefore state the intended representation as clearly as an expression that creates a new result. The benefit applies to later modifications of a value as well as its initial construction.
String operations have byte-sized limits
Dotted operators do not turn arbitrary Unicode text into a bit vector with unspecified encoding. The operator documentation makes characters above 0xFF fatal for these string operations. For other operands represented internally as UTF-8, the operation uses a non-UTF-8 copy. This defines a representation boundary for code that wants to manipulate bits in strings.
The length rules are explicit too. For string OR and XOR, the shorter operand behaves as if it had additional zero bits on the right. For string AND, the longer operand behaves as if truncated to the shorter length. The documentation describes the granularity of that adjustment in bytes. Code working with unequal-length strings therefore needs to choose an operation with the corresponding result length in mind.
These rules make string operations useful without pretending they are ordinary character transformations. A Unicode character above the supported range does not have an implicit bitwise meaning merely because Perl stores it in a scalar. Encoding text and choosing a binary representation remain separate decisions from applying a bitwise operator to that representation.
Numeric bitwise operations have their own interpretation rules. The same manual says their results are integral and normally interpreted as unsigned. use integer changes that interpretation to signed integers. Explicit numeric selection therefore resolves the string-versus-number question, but does not erase the documented signedness behaviour of numeric operations.
There is also an extension compatibility detail. The release notes say numeric operators now pass an additional true argument to overload methods. Methods that reject an unexpected argument count can fail. The notes specifically draw XS authors towards accepting additional arguments. Stabilizing the language feature still requires extension authors to account for the call convention that supports it.
In-place editing changes when replacement happens
The same release improves an operation particularly relevant to short text-processing programs. Previously, perl -i deleted or renamed its input as processing of a new file began. Without a backup, a later write failure, such as a full disk, could lose the original data. The new implementation waits until it has completely written and successfully closed the output.
The release notes describe a work file created in the same directory. Once output is complete, Perl renames that work file over the input. This moves replacement after the point where output success is known. The implementation changes the failure sequence while preserving the familiar in-place editing interface.
That sequence has specific consequences for processes and threads. When a program creates a thread or child process, only the original thread or process performs the final rename. The replacement must happen once. Allowing every continuation of the program to perform it would conflict with that requirement.
Changing directories during processing is another documented boundary. On systems without unlinkat, renameat, and fchmodat, the final rename can fail if the working directory changes. The safety improvement consequently has a platform-dependent consequence for programs that alter their directory while using in-place editing. It is a specific interaction with the delayed filesystem operation.
I consider delayed replacement a substantial improvement for the way I value Perl. A small transformation should not have to reimplement the interpreter editing path merely to avoid deleting its input before output has succeeded. The release explains the remaining process and directory constraints, so the stronger behaviour has a concrete scope.
Small additions preserve more information
Perl 5.28 also permits delete on key/value hash slices. The release notes say this returns the keys together with their deleted values. The operation can therefore retain the association between a selected key and the value removed, instead of requiring a separate reconstruction of those pairs. This is a focused extension to an existing hash operation.
Persistent lexical aggregate variables gain initialization as well. The notes give state @a = qw(x y z) as an example of initializing an array. They distinguish that from initializing a list of persistent lexical variables, which remains unsupported. The improvement applies to an aggregate variable, without making every superficially similar list assignment legal.
Large inode numbers receive another information-preserving change. On platforms whose inode type exceeds Perl native integer types, stat can return the full number as a decimal string. Exact equality then uses eq. Numeric comparison can still fall back to floating point and lose the lower significance of a sufficiently large inode number. Treating the identifier as text preserves information that arithmetic cannot necessarily represent exactly.
Unicode support advances to 10.0 in this release. Separately, experimental script-run regular expressions allow patterns to require compatible scripts, with examples covering digits from one set and word characters from one script. Those constructs retain an experimental warning. Their status differs from the now-stable bitwise feature, even though both appear among the core additions.
That distinction is useful when deciding what a version declaration means for application code. Perl 5.28 includes stable changes, opt-in behaviour, and explicitly experimental syntax. The bitwise feature has reached a point where its warning is gone and its representation choice is documented in ordinary operators. Script runs still announce their experimental status, while in-place editing changes the implementation beneath an existing command-line interface.
The release also introduces a multiconcat opcode that can combine multiple concatenations and, optionally, an assignment into one action. The notes explain that constant-format sprintf expressions using only %s and %% with a fixed argument count can receive the same optimization. Existing concise expressions gain implementation work without requiring another spelling. Together with the explicit bitwise operators, these changes show two ways the release improves familiar Perl code, through a clearer operation choice and through a better implementation of an established expression.