Front page | perl.perl5.porters |
Postings from March 2022
Tie::IxHash and Hash::Utils interaction
Thread Next
From:
Glenn Golden
Date:
March 5, 2022 14:01
Subject:
Tie::IxHash and Hash::Utils interaction
Message ID:
YiNtIeBSgKnxThQv@huh.zplane.com
Dear Porters,
Suppose one wishes to construct an immutable hash which always returns its
keys in presented order. One obvious approach would be via Tie::IxHash
and the lock_hash() function from Hash::Util. But they don't seem to play
well together. Examples below.
RTFMing/Googling did not yield anything suggesting that combining tied
hashes with other "overloaded" hash functionality (e.g. as provided by
Hash::Util) might be problematic, although I can appreciate why it might
be so. So maybe these examples are just demonstrating moronity on my
part ("you shouldn't expect this sort of thing to work"). Or perhaps it's
a genuinely unexpected conflict that might be worthy of a bug report or
a doc warning (in which case I will be happy to file it as such on github).
What say you?
Apologies if this is the wrong place for this question/issue. If so, I'll
open an issue on github.
Thanks. (And as always, h/t for maintaining Perl5.)
Glenn Golden
#----------------------------------------------------------------------
# Example 1: lock_hash() seems to prevent tie()ing with Tie::IxHash.
#----------------------------------------------------------------------
use 5.034;
use warnings;
use strict;
use Hash::Util qw / lock_hash hash_locked /;
use Tie::IxHash;
my %h;
%h = (one => 1, two => 2, three => 3, four => 4);
lock_hash(%h);
print "%h is " . (hash_locked(%h) ? "locked\n" : "not locked\n");
#
# {key,value} pairs displayed in random order, as expected per Perl convention.
#
print "\nBefore assignment to \$h{five}:\n";
while (my ($k, $v) = each %h) { print " $k => $v\n"; }
#
# Naive expectation (WRONG): Call to tie() should succeed, subsequent
# accesses will be displayed in presented order rather than random order.
#
# Observed behavior: Call to tie() fails: "Modification of read-only value".
#
tie(%h, 'Tie::IxHash');
while (my ($k, $v) = each %h) { print "$k => $v\n"; }
print "\n";
#----------------------------------------------------------------------
# Example 2: Tie::IxHash seems to defeat lock_hash() functionality
#----------------------------------------------------------------------
use 5.034;
use warnings;
use strict;
use Hash::Util qw / lock_hash hash_locked /;
use Tie::IxHash;
my %h;
tie(%h, 'Tie::IxHash');
%h = (one => 1, two => 2, three => 3, four => 4);
lock_hash(%h);
print "%h is " . (hash_locked(%h) ? "locked\n" : "not locked\n");
#
# {key,value} pairs displayed in presented order, as expected per Tie::IxHash.
#
print "\nBefore assignment to \$h{five}:\n";
while (my ($k, $v) = each %h) { print " $k => $v\n"; }
#
# Naive expectation (WRONG): Assignment should fail with 'attempt to access
# disallowed key' diagnostic.
#
# Observed behavior: Assignment succeeds, no diagnostic issued.
#
$h{five} = 5;
print "\nAfter assignment to \$h{five}:\n";
while (my ($k, $v) = each %h) { print " $k => $v\n"; }
Thread Next
-
Tie::IxHash and Hash::Utils interaction
by Glenn Golden