2001年3月5日 p5p 本周回顾
注释
您可以通过发送空消息到 perl5-porters-digest-subscribe@netthink.co.uk
订阅本摘要的电子邮件版本。
请将更正和补充发送到 perl-thisweek-YYYYMM@simon-cozens.org
,其中 YYYYMM
是当前年份和月份。
本周我们尝试了一些新的内容,并提供了部分高产移植者的简要传记。如果您想为本部分添加内容,或者对关于您的评论有异议,请通过上述邮箱联系我。
区域设置支持
Andrew Pimlott 提交了一个与 POSIX::tolower
相关的漏洞报告;基本上,它不如 Perl 自身的 lc
本地化敏感。他还发现,在调试器中 lc
未能实现本地化感知。 Nick Ing-Simmons 指出,use locale
是词法作用域的,而调试器处于不同的作用域,这意味着它不会捕捉到这个声明。Andrew 认为这可能是错误(调试器没有假设被调试者的作用域),但如何修复还不清楚。Nick 怀疑第一个问题可能是因为没有调用 setlocale
,但Andrew 报告说这并没有什么帮助。
Andrew 随后开始深入研究 POSIX.pm
,发现 isalpha
完全本地化感知,但 tolower
不是——这是因为 isalpha
是用 XS 编写的,而 tolower
只是调用了 lc
;因为它处于不同的词法上下文中,所以不会捕获到 use locale
。结果是,XS 代码确实在与调用者相同的词法上下文中执行,这相当奇怪。Andrew 指出,没有方法可以使声明动态作用域。他说:
我认为这引发了一些基本问题,但我不确定具体是哪些。很明显,人们希望能够在纯 Perl 中编写正确的 tolower(即与 lc 完全等价,如 POSIX 文档中所述)。一个可能性是类似于 TCL 的“uplevel”,但我迫切希望这不会成为最好的选择。
我询问为什么 POSIX 函数是用 Perl 而不是 C 实现的,Andrew 回复说在某些情况下,这仅仅是通过魔法实现的:Perl 没有正确地在词法上下文中开启和关闭本地化支持,因此一些函数免费继承了支持。Jarkko 以他惯有的方式抱怨本地化,并表示他会查看需要调用 setlocale
的区域,但随后 Andrew 有了一个顿悟:
嗯,看起来我遗漏了一个关键点:本地化支持根本不依赖于“use locale”!这似乎是故意的。Perl 在启动时无条件地调用 setlocale(),之后再也没有调用过(除非您显式使用 POSIX::setlocale())。所以 POSIX::isalpha() 默认情况下尊重 $LANG,即使您从未提及其他本地化声明。
只有在(核心)Perl 在调用本地化敏感的 libc 函数和以自己的方式(例如,硬编码字符语义)做事之间有选择时,本地化声明当前才重要。由于 $! 的字符串值需要调用本地化敏感的函数(strerror()),所以 $! 总是尊重本地化。
您知道为什么 Jarkko 一提到任何与本地化相关的事情就会感到沮丧……
引用 @INC
尼古拉斯·克拉克提供了一个补丁,扩展了鲜为人知的 @INC
中的 coderef 功能,允许传递一个对象;如果您传递一个对象而不是 coderef,则 INC
方法将在其上调用。这使得他能够创建一个实验性 pragma,ex::lib::zip
,它允许您将模块树放入 ZIP 存档中,Perl 将从中提取所需的模块。
然后他还解释了这一切,希望有人能编写一些正式的文档。但没有人这样做,(是我的错,我承诺过但一直没有时间)但他对 coderef-in- @INC
API 的极其有用的解释,以及它所允许的廉价源过滤器 API,可以在这里找到。
简要地说,您可以这样做
BEGIN {
push @INC, \&somesub;
sub somesub {
my ($owncoderef, $wanted_file) = @_;
# Produce a filehandle somehow
if ($got_a_handle) {
return *FH;
} else {
returm undef;
}
}
}
并让您的子例程拦截 use
调用。CPAN 上的 ByteCache
模块就是利用这一点来缓存模块的即时编译版本的。
更多内存泄漏追踪
一些人开始抱怨 5.6.1 的发布延迟,艾伦 提到,由于他所看到的“大量泄漏”,他可能无法在 Solaris 上发布 5.6.1。 萨拉西 不同意
我强烈怀疑您最终将无法在 Solaris 上发布任何版本的 Perl。目前所有的 Perl 版本都有比即将发布的 5.6.1 更多的未修复的“泄漏”,还有一些“真实”的泄漏。
我说“泄漏”,因为这些在启用 arena 清理(这是清理所有泄漏的人的正确视角)的情况下仍然是完全假设的(-DPURIFY enabled build with the arena cleanup suppressed)。然而,这不是真实世界。在现实世界中,arena 清理被启用,并且似乎正在发挥作用(不管您或我说得多么丑陋)。
然后有一些类似的丑陋辩论,关于什么实际上构成了泄漏:艾伦认为任何分配内存并丢失其指针的泄漏都是泄漏;萨拉西只考虑单调进程增长。尼克·克拉克提出,他可以通过重复 use
模块并清除 %INC
来触发萨拉西意义上的泄漏,但这不是情况;泄漏是由于编译器看到 use Module;
时发生的丑陋的伪造造成的。然而,艾伦可以用以下方法触发泄漏:
sub X { sub {} }
因为内部子例程没有被适当地引用计数。艾伦和我急忙寻找 use
泄漏,艾伦发现这两个是相关的。我不知道他是否已经修复了它。
其他新闻,尼古拉斯·克拉克是一个非常坏的人,并成功地将 Boehm 垃圾收集器 编译到 Perl 中。(如 兰达尔 邮件列表中指出的,不再有 Boehm 垃圾!)并找到了将其用作内存泄漏检测器的方法。
奇怪的内存损坏
本周的奇怪错误来自 Jarkko,他发现
$ENV{BAR} = 0;
reset;
if (0) {
if ("" =~ //) {
}
}
在有些平台上运行良好,在有些平台上崩溃;问题在不同平台之间不一致,这意味着具有相同设置的某些机器产生了不同的结果。这显然令人沮丧。尼克·克拉克使它变得更奇怪
./perl 将通过。/usr/local/bin/perl 将段错误。它们是字节对字节的相同。
Jarkko 认为这是一个新问题,但尼克在 5.005_02 中成功地重现了它。艾伦提供了一个令人印象深刻的解释,我强烈建议您阅读以了解如何追踪这类事情,但他没有提供实际的修复方案。
当然,大家对reset
毫无用处的讨论依然如故,甚至有人建议用纯Perl重写操作。
更多Unicode战争
这周有87条消息用于尝试制定一个合理且可接受的Unicode策略。尝试失败了。如果您真的想深入了解,从这里开始可能是个不错的选择。
Switch出问题了
Jarkko报告说,由于某种原因,来自CPAN的Switch 2.01突然开始在bleadperl上测试失败。如果有人能调查这是为什么,并尝试提出一个独立的错误报告,那就太好了。或者,更好的是,修复它。
各种
Olaf Flebbe提供了一系列EPOC修复,适用于那些在Psion上运行Perl的用户;Sarathy修复了一个长期存在的解析器错误。Michael Stevens对文档的POD标记进行了出色的清理工作。《Craig Berry》提交了VMS的configure.com
的一些更新。Daniel Stutz和Ed Peschko都重写了perlcc
。
David Mitchell因一个非常有用的首次修补而应受表扬,这个修补让perl -Dt
能够告诉你哪些变量正在被访问,以及另一个调试选项-DR
,它告诉你栈中SV的引用计数。太酷了,David,谢谢。
有人报告说ExtUtils::Install
有点不规矩,没有检查File::Copy::copy
的返回值;如果有人感兴趣,这很容易修复。(顺便说一句,这是bug ID 20010227.005)
下周见,我,您谦卑而忠诚的仆人,
Simon Cozens - 注释 - 地区支持 - Coderef @INC - 更多内存泄漏搜索 - 奇怪的内存损坏 - 更多Unicode战争 - Switch出问题 - 各种
标签
反馈
这篇文章有什么问题吗?请通过在GitHub上打开问题或拉取请求来帮助我们。