Spec-Zone.ru › Perl 5.30

constant

СОДЕРЖАНИЕ

  • ИМЯ
  • СИНОПСИС
  • ОПИСАНИЕ
  • ПРИМЕЧАНИЯ
    • Список констант
    • Определение нескольких констант одновременно
    • Магические константы
  • ТЕХНИЧЕСКИЕ ПРИМЕЧАНИЯ
  • ОГРАНИЧЕНИЯ
  • СМОТРИТЕ ТАКЖЕ
  • ОШИБКИ
  • АВТОРЫ
  • АВТОРСКИЕ ПРАВА И ЛИЦЕНЗИЯ

ИМЯ

constant - Perl pragma для объявления констант

СИНОПСИС

use constant PI    => 4 * atan2(1, 1);
use constant DEBUG => 0;

print "Pi equals ", PI, "...\n" if DEBUG;

use constant {
    SEC   => 0,
    MIN   => 1,
    HOUR  => 2,
    MDAY  => 3,
    MON   => 4,
    YEAR  => 5,
    WDAY  => 6,
    YDAY  => 7,
    ISDST => 8,
};

use constant WEEKDAYS => qw(
    Sunday Monday Tuesday Wednesday Thursday Friday Saturday
);

print "Today is ", (WEEKDAYS)[ (localtime)[WDAY] ], ".\n";

ОПИСАНИЕ

Этот pragma позволяет объявлять константы во время компиляции.

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

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

ПРИМЕЧАНИЯ

Как и во всех use директивах, определение константы происходит во время компиляции. Таким образом, вероятно, некорректно размещать объявление константы внутри условного оператора (например, if ($foo) { use constant ... }).

Константы, определённые с помощью этого модуля, не могут быть интерполированы в строки, как переменные. Однако конкатенация работает нормально:

print "Pi equals PI...\n";        # WRONG: does not expand "PI"
print "Pi equals ".PI."...\n";    # right

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

use constant ARRAY => [ 1,2,3,4 ];
print ARRAY->[1];
ARRAY->[1] = " be changed";
print ARRAY->[1];

Константы принадлежат тому пакету, в котором они определены. Для ссылки на константу, определённую в другом пакете, укажите полное имя пакета, как в Some::Package::CONSTANT. Модули могут экспортировать константы, а также вызывать их как методы класса или экземпляра, то есть как Some::Package->CONSTANT или как $obj->CONSTANT, где $obj является экземпляром Some::Package. Подклассы могут определять свои собственные константы для переопределения констант базового класса.

Начиная с версии 1.32 этого модуля, константы могут быть определены в пакетах, отличных от вызывающего, включив имя пакета в имя константы:

use constant "OtherPackage::FWIBBLE" => 7865;
constant->import("Other::FWOBBLE",$value); # dynamically at run time

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

Список констант

Константы могут быть списками, содержащими более (или менее) одного значения. Константа без значений возвращает undef в скалярном контексте. Обратите внимание, что константы с несколькими значениями не возвращают последнее значение в скалярном контексте, как можно было бы ожидать. В настоящее время они возвращают количество значений, но это может измениться в будущем. Не используйте константы с несколькими значениями в скалярном контексте.

ПРИМЕЧАНИЕ: Это означает, что выражение, определяющее значение константы, оценивается в списке контекста. Это может привести к неожиданным результатам:

use constant TIMESTAMP => localtime;                # WRONG!
use constant TIMESTAMP => scalar localtime;         # right

Первая строка выше определяет TIMESTAMP как список из 9 элементов, как возвращается localtime() в списке контекста. Для задания строки, возвращаемой localtime() в скалярном контексте, необходимо явно указать scalar ключевое слово.

Константы-списки — это списки, а не массивы. Для индексирования или среза их необходимо заключить в скобки.

my @workdays = WEEKDAYS[1 .. 5];            # WRONG!
my @workdays = (WEEKDAYS)[1 .. 5];          # right

Определение нескольких констант одновременно

Вместо написания нескольких use constant операторов вы можете определить несколько констант в одном операторе, указав вместо имени константы ссылку на хеш, где ключами являются имена констант, которые нужно определить. Очевидно, что все константы, определённые этим методом, должны иметь единственное значение.

use constant {
    FOO => "A single value",
    BAR => "This", "won't", "work!",        # Error!
};

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

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

use constant {
    BITMASK => 0xAFBAEBA8,
    NEGMASK => ~BITMASK,                    # Error!
};

Магические константы

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

use constant E2BIG => ($! = 7);
print   E2BIG, "\n";        # something like "Arg list too long"
print 0+E2BIG, "\n";        # "7"

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

ТЕХНИЧЕСКИЕ ПРИМЕЧАНИЯ

В текущей реализации скалярные константы на самом деле являются встраиваемыми подпрограммами. Начиная с версии 5.004 Perl, соответствующая скалярная константа вставляется непосредственно вместо некоторых вызовов подпрограмм, тем самым экономя накладные расходы на вызов подпрограммы. См. "Constant Functions" в perlsub для получения дополнительной информации о том, как и когда это происходит.

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

sub declared ($) {
    use constant 1.01;              # don't omit this!
    my $name = shift;
    $name =~ s/^::/main::/;
    my $pkg = caller;
    my $full_name = $name =~ /::/ ? $name : "${pkg}::$name";
    $constant::declared{$full_name};
}

ОГРАНИЧЕНИЯ

Константы-списки не встраиваются, если вы не используете Perl версии 5.20 или выше. В версиях 5.20 и выше они всё ещё не являются неизменяемыми, но это может измениться в будущих версиях.

Невозможно иметь подпрограмму или ключевое слово с тем же именем, что и константа, в том же пакете. Вероятно, это хорошо.

Константа с именем из списка STDIN STDOUT STDERR ARGV ARGVOUT ENV INC SIG не допускается нигде, кроме пакета main::, по техническим причинам.

В отличие от констант в некоторых языках, их нельзя переопределять в командной строке или через переменные среды.

Вы можете столкнуться с проблемами, если используете константы в контексте, который автоматически приводит к цитированию слов-без-знаков (так же, как и при любом вызове подпрограммы). Например, вы не можете написать $hash{CONSTANT} , потому что CONSTANT будет интерпретироваться как строка. Используйте $hash{CONSTANT()} или $hash{+CONSTANT} , чтобы предотвратить срабатывание механизма цитирования слов-без-знаков. Аналогично, так как оператор => цитирует слово-без-знаков непосредственно слева от него, вы должны написать CONSTANT() => 'value' (или просто использовать запятую вместо большой стрелки) вместо CONSTANT => 'value'.

СМОТРИТЕ ТАКЖЕ

Readonly - Средство создания неизменяемых скаляров, массивов и хешей.

Attribute::Constant - Создавайте неизменяемые переменные с помощью атрибутов

Scalar::Readonly - Расширение Perl для флага скаляра SvREADONLY

Hash::Util - Набор утилитных подпрограмм для хешей (в основном для блокировки/разблокировки ключей и значений)

ОШИБКИ

Пожалуйста, сообщайте об ошибках и предложениях новых функций с помощью утилиты perlbug(1).

АВТОРЫ

Tom Phoenix, <rootbeer@redcat.com>, при содействии многих других людей.

Множественные объявления констант одновременно добавлены Casey West, <casey@geeknest.com>.

Документация в основном переписана Ilmari Karonen, <perl@itz.pp.sci.fi>.

Эта программа поддерживается Perl 5 Porters. Распространение CPAN поддерживается Sébastien Aperghis-Tramoni <sebastien@aperghis.net>.

АВТОРСКИЕ ПРАВА И ЛИЦЕНЗИЯ

Авторские права (C) 1997, 1999 Tom Phoenix

Этот модуль — свободное программное обеспечение; вы можете распространять и изменять его на тех же условиях, что и Perl сам по себе.

© 1993–2020 Larry Wall and others
Licensed under the GNU General Public License version 1 or later, or the Artistic License.
The Perl logo is a trademark of the Perl Foundation.
https://perldoc.perl.org/5.30.3/constant

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API