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上打开问题或拉取请求来帮助我们。