Change
$hnr{'MAIN'} = { %list1 };
$hnr{'MAIN'}{'ZOP'} = { %list2 };
$hnr{'MAIN'}{'AP'} = { %list2 };
to
$hnr{'MAIN'} = \%list1;
$hnr{'MAIN'}{'ZOP'} = \%list2;
$hnr{'MAIN'}{'AP'} = \%list3;
{ %tied } creates a new (unordered) hash with a copy of %tied contents. That's not what you want,
Update: Alternatively, I think tying anon hashes is perfectly fine:
use Data::Dumper qw( Dumper );
use Tie::IxHash ();
tie my %hnr, 'Tie::IxHash';
%hnr = (
ZOP => {},
AP => {},
Exit => undef
);
tie %{$hnr{'MAIN'}{'ZOP'}}, 'Tie::IxHash';
tie %{$hnr{'MAIN'}{'AP'} }, 'Tie::IxHash';
my @zop_and_ap_init = (
Dev => undef,
Con => undef,
Test => undef,
Exit => undef,
New => undef,
);
%{$hnr{'MAIN'}{'ZOP'}} = @zop_and_ap_init;
%{$hnr{'MAIN'}{'AP'} } = @zop_and_ap_init;
print Dumper(\%hnr);