Perl 5.27.1 returns keys when deleting a hash slice
Deleting a key/value slice now returns enough information to construct a removed subset directly. The development release also changes hash defaults and corrects exception cleanup ordering.
Removing a subset of a hash often requires retaining the association between each selected key and its old value. An ordinary value slice gives back the values, leaving the caller to carry the keys separately. Perl 5.27.1 extends delete to key/value slices, so the result includes both parts of each association. Its release notes identify the change as issue 131328. The distribution history records June 20, 2017.
The addition builds on existing slice syntax. The data documentation dates key/value hash slices to Perl 5.20. Their % prefix returns alternating keys and values, where the @ form returns values alone. The new operation makes that existing distinction available when the selected entries are removed.
I like this extension because it keeps a small text-processing program close to the operation it intends to perform. Extracting named entries and retaining their names is a common enough operation to deserve a direct expression. The useful part is the preserved association, not simply reducing the character count of the program.
A removed subset is already a hash-shaped list
The versioned documentation gives a complete example:
my %h = (blonk => 2, foo => 3, squink => 5, bar => 8);
my %removed = delete %h{'foo', 'bar'};
After the deletion, %removed contains foo => 3 and bar => 8. The original %h retains blonk => 2 and squink => 5. Assigning the alternating result into a hash preserves the names of the extracted entries without constructing a second pairing expression.
The percent sign is significant even though the expression names a subset. This form asks for keys and values together. An ordinary @h{'foo', 'bar'} slice supplies the values at the requested keys. Code that assigns the result into another hash needs the paired form if the original names are meant to become the new hash's keys.
The operation also differs from setting a value to undef. The delete documentation explains that deleting a hash element removes its key, so exists no longer reports it present. Assigning an undefined value leaves the key present. That distinction matters when absence has a meaning separate from a present entry without a defined value.
The slice remains an extraction expression
Supporting deletion does not make the key/value slice a general assignment target. The data documentation says its result cannot be localized or used in assignment. Reading a paired subset and deleting that subset are supported operations, while assigning through the paired result remains outside its contract.
The same documentation describes index/value array slices and includes deletion there as well. Its warning about deleting array elements remains important. Array deletion does not renumber the remaining entries, and its behavior differs from removing an interval with an operation such as splice. The hash example avoids that ambiguity because removing a named association does not imply shifting other names.
For tied hashes, the function documentation gives another boundary. Deletion invokes the tied implementation's DELETE method, whose return behavior depends on that implementation. The simple ordinary-hash example demonstrates the language operation without promising that every external storage abstraction supplies identical deletion results.
Hash implementation changes are independent
The release also retires several older hash functions considered insufficiently secure for Perl. The supported general-purpose choices are SipHash in two variants, Zaphod32 and StadtX. SBOX32 supplies short-string hashing in conjunction with another supported function. By default, the snapshot combines SBOX hashing with StadtX on 64-bit builds and Zaphod32 on 32-bit builds.
These implementation choices do not change the syntax of the deleted subset. They concern how the interpreter hashes its keys. The separation is useful because the same release can extend a hash operation while also changing the work underneath existing hash expressions. A caller should not infer a new ordering guarantee from either change.
The configuration options make the implementation choice explicit for interpreter builders. They can select a supported general-purpose function, disable SBOX32, or set its maximum input length. Those are build decisions. The %h{...} expression continues to describe which associations the program requests, without selecting a hash algorithm for each operation.
Cleanup now precedes exception-result assignment
Another correction in the snapshot concerns the order in which eval exits. Temporary values are now freed before Perl sets $@, whether the evaluation exits normally or through an exception. A temporary object's destructor may itself run an eval, so the order affects the error value visible after the outer evaluation.
The notes show a destructor that catches its own exception. Previously, that inner error could remain in $@ even though the outer eval succeeded. With the corrected ordering, the outer result is assigned after temporary cleanup. I regard that as a useful companion to the slice addition, because both let a short expression retain the result that its own operation is supposed to produce.