【发布时间】:2016-09-09 05:42:10
【问题描述】:
use open qw( :encoding(UTF-8) :std );
上述语句似乎仅在其词法范围内有效,不应影响其范围之外。但我观察到以下情况。
$ cat data
€
#1
$ perl -e '
open (my $fh, "<encoding(UTF-8)", "data");
print($_) while <$fh>;'
Wide character in print at -e line 1, <$fh> line 1.
€
Wide character ... 警告在这里是完美的。但是
$ perl
my ($fh, $row);
{
use open qw( :encoding(UTF-8) :std );
open ($fh, "<", "data");
}
$row = <$fh>;
chomp($row);
printf("%s (0x%X)", $row, ord($row));
€ (0x20AC)
不显示宽字符警告!这是imo这里发生的事情
- 我们正在使用 open pragma 将 IO 流设置为 UTF-8,包括 STDOUT。
- 在同一范围内打开文件。它将字符读取为多字节字符。
- 但打印超出范围。打印语句应显示“宽字符”警告,但事实并非如此。为什么?
现在看下面,有点变化
#3my ($fh, $row);
{
use open qw( :encoding(UTF-8) :std );
}
open ($fh, "<", "data");
$row = <$fh>;
chomp($row);
printf("%s (0x%X)", $row, ord($row));
⬠(0xE2)
现在由于 open 语句超出了词法范围,open 以非 utf-8 模式打开了文件。
这是否意味着use open qw( :encoding(UTF-8) :std ); 语句在全局范围内更改了 STDOUT,但在词法范围内更改了 STDIN?
【问题讨论】:
-
另见 Ricardo Signes 在 2016 年 YAPC NA 上的演讲 A Million Billion Squiggly Characters。
openpragma 的讨论始于 35:44 -
是的,
open qw(:std)会全局更改标准句柄。正如里卡多在上述演讲中所讨论的那样。 -
:std部分没有词法范围,仅更改open()使用的默认层,您甚至不会在 sn-ps 中使用。