open
СОДЕРЖАНИЕ
ИМЯ
open - pragma Perl для установки по умолчанию слоёв PerlIO для ввода и вывода
СИНТАКСИС
use open IN => ':crlf', OUT => ':raw';
open my $in, '<', 'foo.txt' or die "open failed: $!";
my $line = <$in>; # CRLF translated
close $in;
open my $out, '>', 'bar.txt' or die "open failed: $!";
print $out $line; # no translation of bytes
close $out;
use open OUT => ':encoding(UTF-8)';
use open IN => ':encoding(iso-8859-7)';
use open IO => ':locale';
# IO implicit only for :utf8, :encoding, :locale
use open ':encoding(UTF-8)';
use open ':encoding(iso-8859-7)';
use open ':locale';
# with :std, also affect global standard handles
use open ':std', ':encoding(UTF-8)';
use open ':std', OUT => ':encoding(cp1252)';
use open ':std', IO => ':raw :encoding(UTF-16LE)'; ОПИСАНИЕ
Полная поддержка слоёв ввода-вывода теперь реализована, при условии, что Perl сконфигурирован для использования PerlIO в качестве своей системы ввода-вывода (что является значением по умолчанию начиная с версии 5.8 и единственной поддерживаемой конфигурацией начиная с версии 5.16).
Pragma open служит одним из интерфейсов для объявления по умолчанию «слоёв» (ранее известных как «дисциплины») для всего ввода-вывода. Любые операторы open(), readpipe() (также известные как qx//) и аналогичные операторы, найденные в лексическом пространстве действия этого pragmy, будут использовать объявленные значения по умолчанию через переменную ${^OPEN}.
Слои указываются с ведущим двоеточием по умолчанию. Вы можете указать стек из нескольких слоёв как строку, разделённую пробелами. Для получения дополнительной информации о доступных слоях см. PerlIO.
С помощью под-pragma IN вы можете объявить слои по умолчанию для входных потоков, а с помощью под-pragma OUT вы можете объявить слои по умолчанию для выходных потоков. С помощью под-pragma IO (которую можно опустить для :utf8, :locale, или :encoding) вы можете управлять как входными, так и выходными потоками одновременно.
Когда open() получает явный список слоёв (с синтаксисом из трёх аргументов), они переопределяют список, объявленный с помощью этого pragmy. open() также может получить одиночное двоеточие (:) для имени слоя, чтобы переопределить этот pragma и использовать значение по умолчанию, как подробно описано в "Значения по умолчанию и как их переопределить" в PerlIO.
Для преобразования из и в произвольный текстовый кодировку используйте слой :encoding. Сопоставление имен кодировок в :encoding является приблизительным: регистр не учитывается, и у многих кодировок есть несколько псевдонимов. Подробнее и список поддерживаемых локалей см. в Encode::Supported.
Если вы хотите установить слои кодировки, основанные на переменных среды locale, вы можете использовать псевдослой :locale. Например:
$ENV{LANG} = 'ru_RU.KOI8-R';
# the :locale will probe the locale environment variables like LANG
use open OUT => ':locale';
open(my $out, '>', 'koi8') or die "open failed: $!";
print $out chr(0x430); # CYRILLIC SMALL LETTER A = KOI8-R 0xc1
close $out;
open(my $in, '<', 'koi8') or die "open failed: $!";
printf "%#x\n", ord(<$in>); # this should print 0xc1
close $in; Логика :locale подробно описана в "Под-pragma :locale" в encoding, но кратко – она сначала пытается получить nl_langinfo(CODESET), а затем делает предположения на основе переменных среды LC_ALL и LANG.
:locale также неявным образом включает :std.
:std не является слоем, но дополнительным под-pragma. При указании в списке импорта он активирует дополнительную функциональность, позволяющую передавать выбранные слои для входных/выходных дескрипторов стандартным файловым дескрипторам (STDIN, STDOUT, STDERR). Если новые слои и существующий стек слоёв оба заканчиваются слоем :encoding, существующий слой :encoding также будет удалён.
Например, если и вход, и выход выбраны как :encoding(UTF-8), :std будет означать, что STDIN, STDOUT и STDERR также будут иметь :encoding(UTF-8) установленным. С другой стороны, если только выход выбран как :encoding(koi8r), :std приведёт к тому, что только STDOUT и STDERR будут в koi8r.
Эффект :std не лексический, поскольку он изменяет стек слоёв глобальных дескрипторов. Если вы хотите применить только этот глобальный эффект, а не эффект на дескрипторы, открытые в данном пространстве, вы можете изолировать вызов этого pragmy в своём собственном лексическом пространстве.
{ use open ':std', IO => ':encoding(UTF-8)' } До Perl 5.34, :std применял бы только первый предоставленный слой, если он является :utf8 или имеет аргумент слоя, например :encoding(UTF-8). С Perl 5.34 он будет применять тот же стек слоёв, который он предоставляет ${^OPEN}.
ДЕТАЛИ РЕАЛИЗАЦИИ
В классе PerlIO::Layer find есть метод класса, реализованный как XS-код. Он вызывается import для проверки слоёв:
PerlIO::Layer::->find("perlio") Возвращаемое значение (если определено) – это Perl-объект класса PerlIO::Layer, созданный C-кодом в perlio.c. Пока нет ничего полезного, что вы можете сделать с объектом на уровне Perl.
СМОТРИТЕ ТАКЖЕ
"binmode" в perlfunc, "open" в perlfunc, perlunicode, PerlIO, encoding
© 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/open