grep
подходит для небольших наборов, но каждый раз приходится искать весь набор.
Для больших наборов вы можете сделать это немного быстрее, используя List :: Util's any ()функция .Это имеет преимущество перед grep
в том, что оно прекращает поиск, когда совпадает один раз.Предполагая случайные данные, в среднем вы будете искать половину списка.
use strict;
use warnings;
use v5.10;
use List::Util 'any';
use constant allowed_values => qw(value1 value2);
my $main_value = 'value3';
say "Good" if any { $_ eq $main_value } allowed_values;
Тем не менее, этот поиск все еще выполняется по четной части allowed_values
каждый раз.Это несущественно для небольших наборов допустимых значений, но когда оно становится большим, оно может стать медленным.
Вместо используйте хэш в качестве набора .Это немного сложнее в настройке, но это более удобно и будет выполнять то же самое независимо от размера набора.
use strict;
use warnings;
use v5.10;
use constant allowed_values => {
value1 => 1, # any true value will do
value2 => 1,
};
my $main_value = 'value2';
say "Good" if allowed_values->{$main_value};
И если ваш список разрешенных значений длинный, вы можете сгенерировать хеш изсписок, избегающий набора текста.
use constant allowed_values => {
map { $_ => 1 }
qw(value1 value2)
};
Недостатком является то, что «постоянные» ссылки на самом деле не являются постоянными.Только ссылка является константой, содержимое этой ссылки может быть изменено.
allowed_values->{foo} = 42; # this is "fine"
Если это проблема, используйте вместо нее Const :: Fast .
use strict;
use warnings;
use v5.10;
use Const::Fast qw(const);
const my %allowed_values => (
map { $_ => 1 }
qw(value1 value2)
);
my $main_value = 'value2';
say "Good" if $allowed_values{$main_value};
Если вы действительно не нуждаетесь в встроенной константе, и обычно вы этого не делаете.