本周p5p 1999/10/17
- 简介
- 新开发版本 5.005_62
- Unicode字符类
- 模块打包和提议的
import
声明 use fields
允许重叠成员名PREPARE
函数和my Class $foo
声明goto
跳出条件错误- 正则表达式范围错误
use lib
更改- 关于
pack
文档的更多讨论 - MicroPerl
- 各种
简介
本文旨在简要总结本周在perl5-porters邮件列表上讨论的主要和重要主题。
我试图通过省略我认为不感兴趣的线程来增加总结的价值。例如,你经常看到这样的线程
人物A
当你尝试做X时,Perl会出现这个问题。我建议解决方案S。
人物B
解决方案S是不必要的,因为你可以用Y来做。
人物A
不,那不行,因为Z。
人物B
哦,我完全误解了你正在做的事情。
人物C
但是解决方案S会破坏现有代码。
人物A
不,它不会。
人物C
哦,你是对的。我以为你的意思是别的。
人物A
这是一个实现解决方案S的补丁。
我将尝试省略这些死胡同。我还会尝试省略其他类型的消息
人物D
为什么提交补丁S,而我们知道它会破坏旧代码,而且你本来可以做到Y呢?
人物E
Fortran已经采用了解决方案S。Perl不是Fortran;因此解决方案S不好。如果你想用Fortran,你知道在哪里找到它。
人物F
闭嘴。
人物G
不,你闭嘴。
人物H
你的格式化风格深深冒犯了我。你不能用真正的邮件程序吗?
人物I
我如何在Windows 98机器上离线开发CGI脚本?
人物J
P5P不是一个帮助台。
人物K
我正在写邮件报告localtime
函数中的一个错误。它返回了错误的月份。
人物L
在家工作!!!!
我省略的很多东西都是主题相关的,并且具有实际价值,但并不特别有趣。例如,我省略了一些提交了小补丁并被接受而没有讨论的情况。我省略了一些似乎没有普遍兴趣的讨论。例如,本周,Brad Appleton和Ilya Zakharevich就cperl-mode的pod格式化功能进行了交流。
跟踪所有内容都很困难,我可能会偶尔省略你认为重要的东西,或者我可能会误解某些重要问题。您的补充和修订受到欢迎。请将任何更正、建议、补充或修饰发送到[email protected]
,其中YYYYMM
是当前年份和月份。要获取关于perl5-porters的更完整视图,请订阅邮件列表或检查存档。
我想包括存档中相关消息的热链接,但存档不可用,我无法获取URL。这将在未来的一期中得到纠正,即使我们必须自己建立存档。
新开发版本 5.005_62
Sarathy宣布了开发版本5.005_62的发布。可以从CPAN获取。
5.005_61以来的更改包括
- 更多64位增强:64位
vec()
,lfs修复(Jarkko Hietaniemi) our
声明(Larry Wall)sub foo : attrs
,use attrs
已弃用(Spider Boardman)- 配置:新标志
-Accflags=stuff
(Jarkko Hietaniemi) - lvalue子例程中断
\(Foo->bar())
(Ilya Zakharevich和Tuomas Lukka) - 添加了
File::Glob
(曾是Greg Bacon的File::BSDGlob
) - 使用
-DPERL_INTERNAL_GLOB
构建Perl将执行隐式use File::Glob 'globally'
use strict
生成真正的错误,而不是致命警告- 新的
-DPERL_Y2KWARN
选项用于"19$yr"
和sprintf "19%d", $yr
(Ulrich Pfeifer) exists()
在伪散列中工作得更好(Michael Schwern)- 字符范围内无效转义警告(Jarkko Hietaniemi)
- 在
pack
模板中允许注释(Ilya Zakharevich) - 子例程上下文可能太早弹出,导致Tk核心转储(Russel O’Connor)
- 64位安全的
int->ptr
和ptr->int
类型转换宏(Robin Barker) - 修复了
POPSTACK
恐慌 - 修复了修改
@_
时的内存泄漏 %@
“泄漏”,已消失- 在
-c
开关下不运行END
块 die
/warn
转到STDERR
,而不是PerlIO_stderr()
\C{foo}
已重命名为\N{foo}
pack
模板中的Z
始终打包一个空字节POSIX::strftime()
错误(Spider Boardman和Jan Dubois)xsubpp
理解函数指针,未记录(Ilya Zakharevich)h2xs
更具有选择性,并且与不透明类型一起工作(Ilya Zakharevich)use lib
不会保留重复项MakeMaker
支持未安装的Perl,未记录(Ilya Zakharevich)Benchmark
增强(Barrie Slaymaker)- 关于
join(/foo/,...)
的警告(Mark-Jason Dominus) perlcc
支持其他后端(Tom Hughes)- 关于操作码的更多描述性诊断(Michael Schwern)
- Unicode数据库更新到3.0左右(unicode.org)
- EPOC更新(Olaf Flebbe)
- DOS更新(Laszlo Molnar)
- VMS更新(Charles Bailey等人)
- Win32更新:Windows 95支持,更快的
opendir()
,use Shell
支持(Benjamin Stuhl,Jochen Wiedmann,Jenda Krynicky等人) - cygwin更新(Eric Fifer等人)
- JPL更新(Brian Jepson)
- 编译器更新(Vishal Bhatia)
DB_File
更新到1.71(Paul Marquess)PodParser
更新到1.085(Brad Appleton)pod2text
,pod2man
被podlators-0.08
取代(Russ Allbery)Getopt::Long
2.20(Johan Vromans)perlcc.pod
,perlhack.pod
(Nathan Torkington)- 大量的pod调整
- 大量的其他错误修复
Sarathy还表示,他正在将即将发布的版本5.6移入beta模式。
Unicode字符类
Jarkko意识到,由于Perl正在将5.6移入beta模式,这将是提出新功能的最后机会。他希望Perl正则表达式支持POSIX 1003.2的“等价类”功能。这意味着字符集中的某些字符可能被认为是“等价”的,并且符号[=c=]
表示包含与c
等价的所有字符的字符类。
您如何决定哪些字符被认为是“等价”的?Unicode提供了一个定义,使您能够理解像é
这样的字符;作为一个带尖音符号的e
;我们可以让Perl将其理解为与普通e
等价。然后符号[=e=]
将匹配任何e
,é
,è
,ë
或ê
。这可能很有用。
Jarkko还希望人们能够定义自己的等价关系,并且他希望m//
和s///
运算符支持一个新选项,类似于/i
,该选项将表示忽略所有重音符号,再次使用Unicode表来决定什么是一个重音符号。
人们提出了一些潜在问题;例如,在丹麦语中,字符å
(U00E5)被认为与a
完全不同,根本不等同于它。但根据Unicode,å
实际上是一个带有变音符号的a
。(Jarkko:``哈!我正期待一些丹麦人……跳到这里疯狂地挥舞他们的手……)
讨论仍在继续;如果有什么要报告的,我将在下周更新。顺便说一下,Unicode代码图表非常适合浏览。说明哪些字符由哪些其他字符组成的数据库也很吸引人。
模块打包和提议的导入祈使句
Tim Bunce转发了Michael King发送给[email protected]
邮件列表的消息。Michael编写了一个新模块,他将其命名为import
。import
的想法是这样的:假设你有一些只在你公司内部使用的模块。你担心与CPAN模块的命名空间冲突。你可以用以com::yourcompany
开头的名称命名你的内部使用模块,然后使用
use import 'com::yourcompany';
这做了两件事。首先,它在本地机器上的com::yourcompany
空间中定位所有模块并将它们全部导入。但其次,它导入每个com::yourcompany::Foo
模块时移除了com::yourcompany
部分。这意味着,例如,如果你有一个com::yourcompany::Template
模块,你现在可以调用Template->new()
而不是com::yourcompany::Template->new()
。
Michael说这就像Java中的import
关键字。
这引发了一系列有趣的讨论
Andreas König建议Perl应该支持一个
package "www.foo.org";
指令,它与
package org::foo::www;
等效。但Chip Salzenberg说,这通常被认为是一个糟糕的想法,因为组织出于各种原因经常更改URL。例如,foo.com
和bar.com
可能会合并成为foobar.com
。Chip说:CPAN最了不起的事情之一就是它是所有共享Perl模块的既定根命名空间。让我们不要扔掉它!这引发了对如何保留整个模块命名空间的普遍讨论。
Damian Conway指出,我们可以简单地建立一种约定,即如果你有一个PAUSE ID,那么这个模块空间为你保留。例如,Damian的PAUSE ID是DCONWAY;根据这个约定,所有以
DCONWAY::*
开头的模块都属于他。这个方案的问题:Uri Guttman现在将拥有
URI::*
空间,包括URI::URL
模块。Nick Ing-Simmons的PAUSE ID是NI-S
,这不是一个有效的包标识符。John Redford建议一个可以将许多模块打包成一个的模块。他说
然后你可以编写一个打包模块,如下所示
package MyCompany::CGIBundle; use MyCompany::CGI::BobsCode::Foo; use MyCompany::CGI::Test::Bar; use MyCompany::CGI::BobsBetterCode::Foo2; .... use NameSpace::Transitive;
然后人们可以简单地写下
use MyCompany::CGIBundle;
以将
MyCompany::CGIBundle
导出的所有符号重新导出到他们自己的命名空间中。我在2月份写过这样一个模块,所以我决定将其放到CPAN上。现在它作为ModuleBundle可用。Nick Ing-Simmons还指出,他的
Tk::widgets
模块做了一些类似的事情:use TK::widgets qw(Text Entry Canvas)
等价于use Tk::Text (); use Tk::Entry (); use Tk::Canvas();
一些人希望将这个模块的两个功能分开。他们喜欢能够别名命名空间的想法,这样
com::yourcompany::Template
中的对象就可以像在Template
中一样被引用,但他们担心其他功能,即无差别地定位和导入大量内容。有人讨论了命名空间别名祈使句,或者将其功能添加到现有的Alias
模块中。
还有一些不引人注意的讨论:有人想知道如果你说了 use import 'CGI'
会发生什么。Michael 的回答是,这并不是 import
的用途,而且这么做的人会得到他们应得的奇怪行为。但这并没有阻止很多人对此大惊小怪。甚至有一个人说:“如果你想要这个功能,为什么不写一个模块来实现呢?”显然他已经忘记了讨论开始是因为 Michael 编写了一个模块来实现这个功能,并在模块列表中通知,然后 Tim Bunce 将他的笔记转发给了 P5P。
现在,Michael 似乎正在追求 Import
命名空间中的一个名字,并且可能对模块的调用接口做一些修改,以更好地分离他的模块的两个功能。
使用字段允许重叠成员名称
Tuomas Lukka 在 field.pm
中发现了一个问题。问题是这样的:假设你有一个基类和一个派生类,它们都包含一个同名字段,比如 f
。假设方法 m
在基类中定义,并被派生类继承。现在创建一个派生类的对象,并在对象上调用 m
。假设 m
包含修改字段 f
的代码。有两个名为 f
的字段。哪一个将被修改?
你会期望,因为 m
在基类中定义,它应该修改基类的 f
。如果 m
编写正确,它确实是这样做的
package Base;
sub m {
my Base $self = shift;
$self->{f} = 'newvalue'; # Modifies base class field f
}
但如果你不小心写了 my $self
而不是 my Base $self
,它会修改错误的成员
package Base;
sub m {
my $self = shift;
$self->{f} = 'newvalue'; # Modifies DERIVED class field f
}
Tuomas 指出,声明和使用 $self
可能非常分散,并且远处的错误声明可能会在程序中引入难以发现的错误。更糟糕的是,假设对象存储在其他对象内部,所以你有 $object->{subobject}->{f}
而不是 $self->{f}
;在这种情况下,没有任何声明适用,你得到相同的问题。
Tuomas 的解决方案是简单地禁止冲突的字段名称。《fields.pm》和《base.pm》将检测到这种情况,并在检测到派生类正在使用与它的父类具有相同名称的成员时抛出致命异常。
Tuomas 的理由是,目前这非常危险,是“远程动作”,这意味着两个看似无关的声明远离,甚至在不同的文件中,可能会极大地改变第三个位置的子例程的行为。如果找到一种使其更安全的方法,以后可以取消这个禁令,现在似乎没有人使用它。(有人认为他们在使用,但后来意识到他们错了。)
Sarathy 似乎被说服,这种情况至少需要警告。Tuomas 正在推动致命的编译时错误。
PREPARE 函数和 my Class $foo 声明
Ilya 提交了一个补丁,该补丁将使 my Class $foo;
表现得好像你也写了 Class->PREPARE($foo)
,如果存在这样的方法。如果你有 my Class $foo = 'bar'
,赋值将在 PREPARE
调用之后发生。
Sarathy 不喜欢这个实现,原因我不完全理解。Sarathy 不喜欢如果找不到 PREPARE
,编译时会进行 AUTOLOAD
调用。Ilya 通过与 DESTROY
的类比来做这件事,但编译时对 AUTOLOAD
的调用是独特的。(Sarathy:“天哪!”)Sarathy 还反对在编译时而不是在运行时进行 PREPARE
检查;Ilya 说他这么做是为了效率,这样就不必每次执行声明时都进行检查。
萨拉蒂还抱怨说,尽管大多数使用 my Class $foo
的情况不会涉及 PREPARE
,但编译器仍必须为每一个它们调用一次 AUTOLOAD
。伊利亚似乎同意这确实是一个问题。萨拉蒂建议一个pragma,用于声明类的 PREPARE
方法。伊利亚指出,如果从他的补丁中移除自动加载部分,那么 PREPARE
子例程的定义本身就可以作为这样一个pragma。
出现了一个有趣的插曲:奇普表示,如果 PREPARE
的参数是 \$foo
而不是仅仅 $foo
,那么在托帕斯中会简单一些。伊利亚说他不想这样做,因为构建引用的成本与21个“简单”操作相当。这意味着:Perl 在执行每个操作时都会花费一定的时间。对于一些“简单”操作,例如执行标量赋值,实际执行操作的时间主要由指令调度时间决定,因此它们都需要大约相同的时间。据伊利亚所说,构建标量引用需要比这些“简单”操作之一多21倍的时间,构建数组引用需要多50倍的时间。奇普感到惊讶,我也一样。
goto 条件外错误
戴米恩·尼尔报告了一个在5.005_03中触发的bug,该bug会在你使用 goto
从条件块中跳转时出现。他还提供了一份补丁。请注意戴米恩——为新版本提供核心补丁的人值得关注。
萨拉蒂表示,这在开发版本中已经修复了。他的解决方案略有不同。戴米恩的补丁将每个 if
分支包装成单独的块;萨拉蒂的补丁将整个 if
包装成一个块。萨拉蒂希望保留他的补丁,因为它可以使操作树更小,从而使代码在运行时更快。但他指出,如果可以指示窥视孔优化器删除不包含 goto
的块的额外指令,那么戴米恩的方法可能更好。
正则表达式范围错误
法西尔·纳斯姆在使用包含 [\w-]
和 [\w-.]
的正则表达式时遇到了麻烦。Perl 的不同版本对此的处理方式不同,这取决于 -
是否被视为表示范围。5.005_03 解释它就像你写了 [\w\-.]
一样;5.005_62 生成一个语法错误。(“无效范围”。)这是贾尔科干的。关于最佳行为意见不一,特别是鉴于文档似乎支持后者,但法西尔指出,这种变化的行为破坏了旧代码。
拉里建议将其设为警告。贾尔科认为这很棒,并提交了补丁。在此话题上,他还为在字符类中使用 \A
等提供了警告。
use lib 修改
托德·艾林希望 use lib 'foo'
不仅将 foo
追加到 @INC
的前面(它确实这样做了),还删除 @INC
中已存在的任何其他 其他 出现的 foo
。他的动机是:有 use lib
的 mod_perl
脚本具有越来越长的 @INC
列表。
有一些反对意见,但这个修改已经被采纳。
尼克·英格-西蒙斯:向
@INC
注入内容的模块是非常可疑的生物——就像在果汁中添加伏特加。
有关 pack 文档的更多讨论
关于 pack
文档的讨论结束了。我不会提这个,除非
萨拉蒂:你建议[格式说明符]
@*
应该意味着什么?伊利亚:叫警察。
MicroPerl
这差点从我这里滑过,但我写信问伊利亚这是关于什么的。以下是他所说的话
在不使用Configure支持的情况下构建Perl。首先,你构建一个修改过的版本(nanoperl),使用它构建一个功能缺失但能正常工作的版本(microperl),然后使用这个版本运行
Configure.PL
,这将生成类似于config.sh
的副本,然后你继续使用miniperl和perl。提供的目标crazyperl与上述分类的nanoperl非常接近。对提供的
micro0/config.sh
进行一些小的修改(当错误被修复时)应该能生成一个microperl。目前crazyperl通过了大量测试。这应该还有更多的改进(显然代码中有支持在没有找到非可移植服务的情形,但存在一些错误)。
你不高兴我这么问吗?我当然很高兴。
各种
还有大量的错误报告、错误修复、问题、答案,以及少量的人身攻击和垃圾邮件。
直到下周,我仍然是你谦卑且顺从的仆人,
标签
反馈
这篇文章有什么问题吗?请通过在GitHub上打开一个问题或拉取请求来帮助我们。