my $hash = { foo => { bar => 1 } };
Internals::SvREADONLY( $hash->{foo}{bar}, 1 );
$hash->{foo}{bar} = 2;
производит
Modification of a read-only value attempted at -e line 4.
Но это фатальная ошибка, и она не содержит трассировки (если не используется Carp :: Always).
Я бы порекомендовал добавить set magic к скаляру.
use Carp qw( cluck );
use Variable::Magic qw( wizard cast );
my $wizard = wizard(
set => sub {
cluck("Warning: Modification of a read-only value attempted");
},
);
my $hash = { foo => { bar => 1 } };
cast( $hash->{foo}{bar}, $wizard );
$hash->{foo}{bar} = 2;
производит
Warning: Modification of a read-only value attempted at -e line 6.
main::__ANON__(SCALAR(0x4200c90), undef) called at -e line 12
eval {...} called at -e line 12
То же самое можно сделать с помощью tie
, но это будет дороже.(Связанные переменные построены на magic
.)