Spec-Zone.ru › Perl 5.38

константа

СОДЕРЖАНИЕ

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

ИМЯ

constant - Perl-прагма для объявления констант

СИНТАКСИС

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";

ОПИСАНИЕ

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

Когда вы объявляете константу, например, 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, соответствующая скалярная константа вставляется непосредственно вместо некоторых вызовов подпрограмм, тем самым экономя накладные расходы на вызов подпрограммы. См. "Функции-константы" в 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 v5.20 или более позднюю версию. В v5.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).

АВТОРЫ

Том Феникс, <rootbeer@redcat.com>, с помощью многих других людей.

Несколько объявлений констант одновременно добавлены Кейси Вестом, <casey@geeknest.com>.

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

Эта программа поддерживается разработчиками Perl 5. Распространение CPAN поддерживается Себастьен Апергис-Трамони <sebastien@aperghis.net>.

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

Авторские права (C) 1997, 1999 Том Феникс

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

© 1993–2023 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.38.0/constant

Spec-Zone.ru

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