Я хочу изменить этот код с использования хеша на массив, но я не могу найти хороший пример для продолжения. Кто-нибудь может посоветовать? Пока я только намекаю на использование [ ] во второй строке.
my @subscriptions = ();
$self->{'serverMap'} = {};
foreach my $service( "pmservice", "saservice" ) {
my $r_serverMap = enmGetServiceGroupInstances($self->{'site'}, $self->{'date'}, $service);
while ( my ($server, $serverId) = each %{$r_serverMap} ) {
push ( @subscriptions, {'server' => $server, 'prog' => 'JBOSS'} );
$self->{'serverMap'}->{$server} = $serverId;
}
}
return \@subscriptions;



Во-первых, эти два назначения не нужны:
my @subscriptions = ();
$self->{'serverMap'} = {};
Первый ничего не делает, а второй ничего полезного. Когда вы объявляете массив с
my @subscriptions;
тогда он создается пустым. Добавление = () к определению ничего не дает.
И явная установка $self->{'serverMap'} как пустого анонимного хеша бесполезна. Когда вы начинаете помещать данные в $self->{'serverMap'}, вы можете решить, в каком формате должны быть эти данные.
Во-вторых, вы говорите, что хотите заменить хеш массивом. Я предполагаю, что это хэш, который в настоящее время хранится в $self->{'serverMap'}, который вы хотите заменить. Это просто. Просто замените строку:
$self->{'serverMap'}->{$server} = $serverId;
с участием
push @{ $self->{'serverMap'}->{$server} }, $serverId;
Фактически, давайте избавимся от всей этой ненужной пунктуации одновременно:
push @{ $self->{serverMap}{$server} }, $serverId;
Готово. Первоначально $self->{'serverMap'} содержал ссылку на хэш, теперь он содержит ссылку на массив.
Конечно, это только половина дела. Теперь вы храните данные как массив, но вам также необходимо получить доступ к данным как к массиву. Где-то в вашем коде вы будете смотреть на данные в $self->{'serverMap'} - и теперь их тоже нужно изменить, иначе ваша программа перестанет работать.
См. Также предыдущий вопрос этого парня Преобразование кода с использованием хеша в массив
Всегда присваивайте значение своим переменным. Несколько лет назад mod_perl использовался для повторного использования пространства данных без его повторной инициализации. Переменные, которым не было присвоено значение при объявлении, будут использовать значение из предыдущего запуска. Эта проблема была исправлена, но кто знает, когда появится новая идея, которая будет делать то же самое. Возьмите в привычку программировать в защитной манере: всегда присваивайте значение своим переменным.
@shawnhcorey: Прошло много времени, и я успешно забыл большую часть того, что знал о mod_perl, но разве он не использовал повторно только переменные пакета? Он видит вашу программу как подпрограмму, поэтому любые лексические переменные будут правильно инициализированы.
mod_perl.
@ Дэйв: "разве это не только повторное использование переменных пакета" Я думаю, это очень вероятно. Простое сохранение и перезагрузка образа памяти вряд ли восстановит лексические данные в кадре стека, потому что это мобильный, и я думаю, что Apache умнее этого. Восстановление переменных пакета кажется хорошей идеей, если вы знаете, что это происходит.
@Borodin Apache не было, но теперь он есть. И это не «новая» идея. Ему более 50 лет. А когда дело доходит до программистов, это не имеет значения. Сделайте все явным. «Шумный» лучше, чем расплывчатый.
@shawn: Итак, вы говорите, что Apache "вещь" устарел и исправлен, но мы все равно должны кодировать его, вместе с любыми "новые вещи", которые имеют ту же ошибку и которые могут быть наложены на нашу программу без нашего ведома? Это еще хуже. Придерживайтесь C.
@shawn: Вы также инициализируете все скалярные переменные нулями 0 или пустой строкой ""? Теперь возникает загадка: что это должно быть? И мир погибнет, если mod_perl или что-то столь же неприятное установит его на undef. Что нам следует сделать?
такой же, но выглядит короче
my @subscriptions;
foreach my $service( "pmservice", "saservice" ) {
$self->{serverMap} = enmGetServiceGroupInstances($self->{'site'}, $self->{'date'}, $service);
push @subscriptions, map {
+{ server => $_, prog => 'JBOSS' }
} keys %{ $self->{'serverMap'} };
}
Вы не можете просто преобразовать хеш в массив без дополнительной дизайнерской работы. Хеши используют строки как ключи, тогда как индексы массивов являются целыми числами. Все, что содержится в
$server, необходимо преобразовать в индекс массива, и у вас больше не будет этой строки в структуре$self.