Perl и фиксированные ключи в хеше.
Некоторое время назад мне приходилось писать довольно большой проект на PHP. Тогда очень хотелось от хешей возможности зафиксировать множество ключей, чтобы не отлавливать по десяткам файлов опечатки в названиях полей сложных многоуровневых структур данных.
Тогда решения не нашлось. И сейчас PHP для меня лично уходит потихоньку в прошлое, т.к. в perl нахожу все больше интересных возможностей, которых раньше не хватало.
Так вот, по поводу фиксированного набора ключей, вот пример объекта на основе такого хеша:
package some;
use warnings;
use strict;
use Hash::Util qw{lock_keys};
sub new
{
my $class = shift;
my %hash;
my @keys = ("one", "two", "three", "four", "five");
my $self = bless \%hash, $class;
lock_keys %hash, @keys;
return $self;
}
1;
Теперь при выполнении инструкция $some->{‘there’} произойдет ошибка:
Attempt to access disallowed key 'there' in a restricted hash at ./test.pl line 11.
Причем сделано это не через Tie, чего я сначала опасался, а собственными средствами компилятора, т.е. должно работать очень быстро.
Но вообще-то, в каждой книге по ООП-прогрммированию обязателно замолвят слово о том, что открытые свойства класса это не очень хорошо, и что их значения предпочтительней изменять с помощью методов. А ведь их лень писать для каждой переменной!! Но хорошие языки тем и отличаются, что на них вовсе не сложно писать красиво и правильно. Смотрим, что предлагает Perl (пример из документации):
package Foo;
use base qw(Class::Accessor);
Foo->mk_accessors('foo'); # или mk_ro_accessors(qw{ one two three }) для read-only полей
my $obj = Class->new({ foo => 42 });
print $obj->foo; # 42
$obj->foo("24");
print $obj->foo; # 24
Ну вот и все! Теперь если захочется изменить поведение объекта таким образом, чтобы при изменении свойства foo, менялось также значение bar, достаточно реализовать самостоятельно нужную функцию, а править использующий класс код не нужно.
Все-таки perl язык великий и могучий, этого у него не отнять!
