Immutable な hashref, arrayref たまに欲しくなりますが Internals::SvREADONLY() はクセが強すぎてあまりオススメできないです。

たとえ次のコードの挙動を言い当てられたとしても、赤の他人(≒ 半年後の自分)が見た時に分かるかどうかは怪しいかと。

use strict;
use warnings;
use Data::Lock 'dlock';

my $foo = { bar => "baz" };
dlock($foo);

eval { my $b = $foo->{b} };

if ($@) {
    warn "oops: $@";
} else {
    warn "yay";
}

謎めいたランタイムエラー起こすよりも定数は全部サブルーチンとして記述してあった方がコンパイルに失敗してくれて嬉しい感じがします。

ちなみにConst::Commonというのを書いた | おそらくはそれさえも平凡な日々 を見て思ったんですが、似たような事やってくれるのは過去にかいてました( 定数を定義するのを楽にする Constant::Exporter を書いた - stfuawsc) 他にも Exporter::Constants とかもありますね。