В качестве альтернативы, вы можете просто не связывать части вашей программы с
глобальная переменная. Рассмотрим, что происходит, когда вы используете этот хеш в одном модуле:
package Foo;
use MyApp::Versions qw(%versions); # i'm going to pretend that you didn't call the module "revs".
some_function {
while(my ($k, $v) = each %versions){
return if $some_condition;
}
}
А потом в каком-то другом модуле:
package Bar;
use MyApp::Versions qw(%versions);
some_other_function {
while(my ($k, $v) = each %versions){
print "$k => $v\n";
}
}
А затем используйте оба модуля:
use Foo;
use Bar;
some_other_function;
some_function;
some_other_function;
В зависимости от $some_condition
, some_other_function производит разные
результаты каждый раз, когда вы называете это. Получайте удовольствие отлаживая это. (Это
скорее проблема each
, чем проблема глобального состояния; но выставляя
внутренняя реализация, вы позволяете своим абонентам делать то, что
Вы не собирались, и это может легко сломать вашу программу.)
Также сложно переписать Foo и Bar, когда вы меняете жестко запрограммированный код.
хэш для поиска в базе данных по требованию, например.
Таким образом, реальным решением является разработка правильного API и экспорт этого
вместо всей переменной:
package MyApp::Versions;
use strict;
use Carp qw(confess);
use Sub::Exporter -setup => {
exports => ['get_component_version'],
};
my %component_versions = ( foo => 42 ); # yes, "my", not "our".
sub get_component_version {
my ($component) = @_;
return $component_versions{$component} ||
confess "No component $component!"
}
1;
Теперь ваш модуль проще в использовании:
package Foo;
use MyApp::Versions qw(get_component_version);
sub some_function {
die 'your foo is too old'
unless get_component_version('foo') >= 69;
return FooComponent->oh_hai;
}
Теперь some_function не может испортить some_other_function, и когда вы
изменить реализацию get_component_version, остальные ваши
программа не заботится.