Действительно ли следует получить и особенно установить глобальные переменные модуля Perl непосредственно?

Я задавался вопросом, что лучшая практика в Perl расценивает получение - или, что еще более важно, устанавливая - глобальная переменная некоторого модуля путем прямого доступа $Module::varName в случае, если модуль не обеспечил метод считывания/метод установщика для него.

Причиной это плохо пахнет мне, является то, что это вид обходит инкапсуляцию. Просто, потому что я могу сделать это в Perl, я не совсем уверен, что я должен (принимающий там, на самом деле альтернатива, такая как добавление метода считывания/метода set к модулю).

7
задан DVK 28 May 2010 в 14:13
поделиться

4 ответа

Инкапсуляция не нарушается, если переменная является частью общедоступного API. (Если это не так, это другое дело.)

Я думаю, что прямой доступ предпочтительнее, так как он позволяет вам использовать преимущества динамической области видимости:

local $Module::varName = 42;

Это снижает вероятность конфликтов с другим кодом, использующим Модуль .

8
ответ дан 7 December 2019 в 03:12
поделиться

Если модуль не предоставляет средства доступа, создайте его, используйте его и отправьте патч.

1
ответ дан 7 December 2019 в 03:12
поделиться

Разве санация ввода / обработка ошибок не является сутью инкапсуляции?

Если в этом нет необходимости, то можно возразить против реализации геттеров и сеттеров, которые затем выглядеть глупо вроде sub set_variable {$ variable = shift; } .

Имейте в виду, проще использовать set_variable (42) , чем предлагает Майкл !

-2
ответ дан 7 December 2019 в 03:12
поделиться

Глобальные переменные модуля были в моде в прошлом, но считались «дурным тоном» в качестве интерфейса в современном Perl. Важно понимать, что Perl исполнилось 22-23 года, и стили и методы работы изменились. :) Обратите внимание, что бывают случаи, когда это все еще уместно, потому что есть несколько очень хороших функций, которые идут вместе с переменными пакета. Как обычно, увидеть, какое хорошее решение может быть хорошим решением, - вопрос опыта и практики.

Чтобы понять, как лучше всего использовать переменные пакета, вам действительно нужно понять, как работает local . См. Справку по perldoc local . Local позволяет вам взять переменную пакета, например $ My :: Variable в пакете My , и создать ее версию с динамической областью видимости . Обычно, если вы меняете $ My :: Variable на месте, это повлияет на всю вашу программу и будет сохраняться. Для небольших программ это может не иметь большого значения. Для больших это может иметь катастрофические побочные эффекты. local позволяет вам временно изменять эту переменную, которая ограничена вашей текущей областью действия.

Вот как это работает:

use 5.012;
use warnings;

package My;

our $Variable = 5;

package main;

say $My::Variable; # prints 5
$My::Variable = 7;
say $My::Variable; # prints 7
{  # create a new lexical scope
    local $My::Variable = 10; # create a new dynamic scope for $My::Variable
                              # that will persist to the end of the lexical scope
    say $My::Variable;  # prints 10
}
say $My::Variable;  # end of the lexical scope for the localized
                    # $My::Variable, so prints 7 again

Фактически, он позволяет безопасно использовать переменные пакета.К сожалению, не все знают о local, поэтому часто затирают глобальную переменную. Документирование правильного использования (например, local ) всегда помогает.

Геттер / сеттер с правильной инкапсуляцией объекта предотвращает многое из этого, но не всегда. Чтобы заставить его работать так, как это делает локальная переменная, вам придется проделать много дополнительной работы. Самое приятное в возможности локализовать переменную пакета - это то, что вы можете очень легко вносить временные изменения, например, для переменной отладки. Обычно вам нужно использовать шаблон вроде:

{
    my $current_variable  My::get_variable();
    $My::set_variable($new_value);

    # Do code work

    $My::set_variable($current_variable);
}

С local это становится:

{
    local $My::Variable = $new_value;

    # do code work
}

(Кстати, я бы хотел, чтобы вы могли сделать то же самое и с лексическими переменными по той же причине ... но вы не можете.) Так что для некоторых вещей переменные пакета могут иметь смысл . Это зависит от того, как вы хотите его использовать. Такие вещи, как

  • Отладочные переменные
  • Глобальная конфигурация, которую не следует / не следует часто менять

Однако, если что-то, что делает, необходимо регулярно менять, например

  • Регулярно используемые переменные (см. Ужасный интерфейс для File :: Find )
  • Временная конфигурация
  • «Объектные» переменные

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

2
ответ дан 7 December 2019 в 03:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: