Есть ли встроенная функция для очистки всех значений переменных - PullRequest
4 голосов
/ 17 мая 2011

Я ищу способ очистки всех моих массивов в программе на Perl.

В настоящее время я вызываю подпрограмму, которая явно "сбрасывает" все массивы:

sub clear_arrays{(@array1,@array2,@array3)=((),(),());}

Это заставляет меня находить все массивы в программе и буквально ссылаться на них в подпрограмме.

Я посмотрел на perldoc для reset, undef и delete, но не смог интерпретировать ни один из них так, чтобы очистить все массивы.

Isесть встроенная функция Perl, которая может сделать это?

Если нет, есть ли функция, которая возвращает массив всех переменных массива?

Пример:

my @prog_arrays = getarrays();
foreach(@prog_arrays){$_ = ();}

Где getarrays() может быть встроеннымв функции Perl, которая возвращает любые / все инициализированные массивы в программе.


РЕДАКТИРОВАТЬ:
Моя конкретная ситуация включает в себя только два глобальных массива, которые необходимо сбросить.Я расширил вопрос из любопытства, а не необходимости.По сути, мои глобальные значения @email_subject & @email_msg.

У них есть значения, вставленные в них по мере выполнения сценария и сбора / анализа данных.В конце сценария отправляется сообщение электронной почты, и сценарий может выполняться снова в зависимости от переменной условия цикла.

Если он снова запустится, мне нужно очистить эти 2 глобальных значения, чтобы они могли снова объединиться во время следующего цикла цикла.Это не убивает меня, чтобы очистить эти два массива с помощью буквальной ссылки, но мне просто интересно, есть ли в Perl какая-то встроенная функция для очистки массивов без буквальной ссылки на них.

Возможно, это не лучший способвыполнить это, но это был первый интуитивный вариант, который я рассмотрел.

Ответы [ 3 ]

19 голосов
/ 17 мая 2011

Не используйте глобальные массивы.Это так просто.Лексические массивы ограничены областью, в которой они объявлены, и автоматически запускаются пустыми при входе в область.

Если вы должны использовать глобальные переменные, отслеживание их всех в одном месте - это хорошая идея, поэтому очисткаони не должны быть трудными.

Кто-то однажды опубликовал позорный инструмент для perlmonks, чтобы делать то, что вы хотите.Код был отозван после много критики всей идеи;Вы можете прочитать некоторые критики здесь: http://www.perlmonks.org/index.pl?node_id=349496

8 голосов
/ 17 мая 2011

Тот факт, что вы хотите, чтобы это кричало "плохой дизайн" для меня.Однако при условии, что вы точно знаете, что делаете с этой радиоактивной цепной пилой, вы можете сделать это, обратившись к хэшу глобальной таблицы символов %:: или %main::.(Двоеточия являются частью имени.) Этот хеш содержит отображение каждого определенного глобального символа на ссылку на его переменную.

Что-то вроде этого должно быть достаточно:

for my $ref (values %::) {
    @{$ref} = ();
}

Отредактировано для удаления проверки ссылок на массивы.Все значения на самом деле являются ссылками на typeglob, поэтому нет необходимости проверять.

6 голосов
/ 18 мая 2011

Как уже упоминалось в других ответах, ваш запрос говорит о более серьезной проблеме с дизайном вашей программы.Вам следует либо использовать лексические выражения, которые выпадают из области видимости, либо тщательно управлять всеми вашими глобальными массивами, и создать функцию, которая очистит их для вас.

Если вы настаиваете на том, чтобы забивать каждый массив в вашем пространстве имен, по адресухотя бы позаботьтесь и убедитесь, что вы не записываете значения, которые могут понадобиться Perl:

for (keys %::) {  # for everything in `package main;`
    if (*{$::{$_}}{ARRAY}) {  # if there is an array in the slot
        # clear it unless it is a "special" array
        @{$::{$_}} = () unless /^(?:INC|ISA|EXPORT|EXPORT_OK|ARGV|_|\W)$/
    }
}

Я бы написал так:

my @global_arrays = \our (@foo, @bar, @baz);
sub clear_global_arrays {
    @$_ = () for @global_arrays
}

ЭффектТо же самое для рассматриваемых массивов, но это не рискует забить то, что вы не собирались.Вы могли бы даже использовать my вместо our во втором примере, тогда как первый пример требует, чтобы переменные были в таблице символов (также определенной как our).

...