use 5.006; use strict; use Exporter (); use Carp (); ####################################################### package Const; # allows export of function to faciliate constant usage ####################################################### our @EXPORT_OK = qw/Const ConstHash ConstArray/; our @ISA = qw/Exporter/; sub Const ($$) { tie $_[0], 'ConstScalar', $_[1] } sub ConstHash (\%$) { tie %{ $_[0] }, 'ConstHash', $_[1]; } sub ConstArray (\@$) { tie @{ $_[0] }, 'ConstArray', $_[1]; } ############################################# package ConstScalar; # scalars set on tying, altering causes croak ############################################# use Tie::Scalar (); our @ISA = qw/Tie::StdScalar/; sub STORE { Carp::croak "fatal: Const cannot be altered" } ########################################### package ConstHash; # hashes which are fully set on tying, # altering, or accessing unset keys croaks ########################################### use Tie::Hash (); our @ISA = qw/Tie::StdHash/; sub TIEHASH { bless { %{$_[1]} }, $_[0] } # shallow clone sub STORE { Carp::croak "fatal: ConstHash cannot be altered" } sub DELETE { Carp::croak "fatal: ConstHash cannot be altered" } sub CLEAR { Carp::croak "fatal: ConstHash cannot be altered" } sub FETCH { if (exists $_[0]->{$_[1]}) { return $_[0]->{$_[1]} } else { Carp::croak "fatal: key '$_[1]' doesn't exist in this ConstHash" } } ############################################# package ConstArray; # Arrays which are fully set on tying, # altering or accessing unset indexes croaks ############################################# use Tie::Array (); our @ISA = qw/Tie::StdArray/; sub TIEARRAY { bless [ @{$_[1]} ], $_[0] } # shallow clone BEGIN{ #lazy shortcut for (qw/STORESIZE STORE CLEAR POP PUSH SHIFT UNSHIFT DELETE SPLICE/) { eval "sub $_ { Carp::croak 'fatal: ConstArray cannot be altered' }"; } } sub FETCH { if ($_[1] > $#{$_[0]}) { Carp::croak "fatal: array element $_[1] does no t exist in this ConstArray" } $_[0]->[$_[1]]; } ############################################# 42;