open 也可能指代函数:open

内容

名称

open - 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 作为其 IO 系统(自 5.8 版本以来一直是默认设置,并且自 5.16 版本以来是唯一支持的配置),现在已实现对 I/O 层的全面支持。

open 编译指示用作声明所有 I/O 的默认“层”(以前称为“规则”)的接口之一。在该编译指示的词法范围内找到的任何 open()、readpipe()(也称为 qx//)和类似运算符都将通过 ${^OPEN} 变量使用声明的默认值。

层通常以冒号开头指定。您可以将多个层作为以空格分隔的字符串指定。有关可用层的更多信息,请参见 PerlIO

使用 IN 子编译指示,您可以声明输入流的默认层,使用 OUT 子编译指示,您可以声明输出流的默认层。使用 IO 子编译指示(对于 :utf8:locale:encoding 可以省略),您可以同时控制输入和输出流。

当 open() 给定一个显式的层列表(使用三参数语法)时,它们会覆盖使用该编译指示声明的列表。open() 也可以给定一个冒号 (:) 作为层名称,以覆盖该编译指示并使用 "PerlIO 中的默认值以及如何覆盖它们" 中详细说明的默认值。

要从任意文本编码转换到任意文本编码,请使用 :encoding 层。:encoding 中的编码名称匹配很宽松:不区分大小写,并且许多编码都有多个别名。有关详细信息和支持的语言环境列表,请参见 Encode::Supported

如果您想根据您的语言环境环境变量设置您的编码层,您可以使用 :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 的逻辑在 "encoding 中的 :locale 子pragma" 中有完整描述,但简而言之,它首先尝试使用 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 的效果不是词法上的,因为它修改了全局句柄的层堆栈。如果您希望只应用此全局效果,而不应用对在该作用域中打开的句柄的效果,则可以在其自己的词法作用域中隔离对该 pragma 的调用。

{ 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 类,该类由 perlio.c 中的 C 代码创建。目前,您在 perl 级别上无法对该对象做任何有用的操作。

另请参阅

"perlfunc 中的 binmode""perlfunc 中的 open"perlunicodePerlIOencoding