Perl笔记

Wednesday, September 13, 2006

Pugs: Interview: Perl 6 on Perl 5

登在Pugs官方blog的采访Pugs: Interview: Perl 6 on Perl 5中,负责开发v6模块的 Flávio Soibelmann Glock(fglock)透露了许多v6开发的情况:

总体上,最终目标——v6-Compiler模块(v6/v6-Compiler),用Perl6实现Perl6。

“v6.pm”是一个自举编译器(perl5/Pugs-Compiler-Perl6)。这意味着v6.pm在Perl 6能自己编译自己前,被用作编译Perl 6的编译器。

v6.pm使用了数个CPAN模块:Pugs::Compiler::Rule (regexes), Data::Bind (signatures), Moose (objects),Parse::Yapp (precedence parser)。

这个模块目前通过了Perl 6测试套件的10%。它提供了语言的基础:语句,表达式,还有类。它还包括正则表达式和语法,这些也是编写编译器所需的。

编译器的若干部分用Perl 6编写,用v6.pm自身编译。CPAN上的Pugs::Compiler::Rule模块的语法用Perl 6编写,用v6.pm编译成Perl 5。

性能:

编译速度是100行每秒,代码有缓存——只编译一次。

生产的代码已经相当的优化,运行在perl5的速度上。


最终目标

v6.pm 的目标是能够编译“真正”的v6-Compiler(p6-on-p6)。但是,因为v6.pm必须“足够正确”和“足够快”,它也能用来编写一般用途的模块或程序。

所使用的“.pmc”文件的角色

".pmc"被用于perl5缓存文件。Perl5同时找到".pm"和".pmc"文件,它执行".pmc"文件。

当v6.pm编译一个".pm"时,它把perl 5代码dump下来作为".pmc"。下次执行,perl5会加载编译后的版本。这将变得很快。

v6项目是帮助继续用Perl5的人还是针对想要用Perl 6的人?

主要是为了perl5程序员,保证Perl5可以兼容Perl 6—双向兼容。

Perl5 程序员可以直接使用底层模块——Moose,和Pugs::Compiler::Rule——v6.pm就是“syntax layer”。

哪部分Perl 6不可能依此实现?

一些perl6功能可能在perl5中很缓慢——如协同进程,但并非不可能。

如何尽早尝试Perl 6?

从CPAN安装v6,依赖的模块可以自动补完。

一些模块,如PadWalker和Data::Bind需要C编译器。Windows用户可以用 vanilla-perl发行版,它带有C编译器。

如何参与和帮助

到freenode的#perl6频道来。

Monday, September 11, 2006

Devel::DProf - a Perl code profiler

使用方法:
perl -d:DProf test.pl

UTF8下中文处理

发信人: happierbee (吾生也有涯,而知也无涯), 信区: Perl
标 题: UTF8下中文处理
发信站: 水木社区 (Mon Sep 11 21:22:53 2006), 站内

我来总结一下吧。先建一个文件,写上 中文 两个字。运行下面一个程序:

use strict;
use warnings;
use Encode;
my $str_code = "中文";
my $file = "test.txt";

open(my $fh, $file) || die "Can't open file $file: $!";
chomp(my $str_file = <$fh>);
close $fh;

open(my $fh_utf8, "<:utf8", $file) || die "Can't open file $file: $!";
chomp(my $str_fileu = <$fh_utf8>);
close $fh_utf8;

test_utf8($str_code, "code");
test_utf8($str_file, "file");
test_utf8($str_fileu, "file(utf8 layer)");
# print $str_code, "\n";
# print $str_file, "\n";
# print $str_fileu, "\n";

Encode::_utf8_on($str_code);
Encode::_utf8_on($str_file);
test_utf8($str_code, "code");
test_utf8($str_file, "file");

sub test_utf8 {
my ($str, $type) = @_;
if ( Encode::is_utf8($str) ) {
print "String from $type, utf8 flag is on."
} else {
print "String from $type, utf8 flag is off."
}
my @chars = split('', $str);
# print join("\t", @chars), "length: ", scalar(@chars);
if (scalar(@chars)==2) {
print " Can match chinese character.";
} else {
print " Can't match chinese character.";
}
print "\n";
}

结果如下:
String from code, utf8 flag is off. Can't match chinese character.
String from file, utf8 flag is off. Can't match chinese character.
String from file(utf8 layer), utf8 flag is on. Can match chinese character.
Turn on utf flag:
String from code, utf8 flag is on. Can match chinese character.
String from file, utf8 flag is on. Can match chinese character.

所以如果要想使用汉字作为一个字符的特性,就要在 open 里指明 io layer 为
utf8,同样,输出指明 utf8,然后在脚本里写 use utf8。
这样你就不用担心 utf8 下的乱码,又能享受汉字做为一个字符来写正则表达式的
的畅快。
如果不知道我上面说的意思,我就给一个例子:
use strict;
use warnings;
use Encode;
use utf8;

my $file = "test.txt";
my $outfile = "test-out.txt";
# open(my $fh, $file) || die "Can't open file $file: $!";
# open(my $out, '>:utf8', $outfile) || die "Can't open file $outfile: $!";
# select $out;
open(my $fh, '<:utf8', $file) || die "Can't open file $file: $!";
binmode STDOUT, ":utf8";
while (<$fh>) {
if (/[汉]/) {
unless (Encode::is_utf8($_)) {
Encode::_utf8_on($_);
}
print $_;
}
}

test.txt 中的内容是:"求\n汉\n汁\n汗\n汕\n江\n"(每个汉字一行的意思)。
这个例子中,有好几个组合:
1. 不使用 utf8 指令,open 中也不使用 utf8。
这时所有行都匹配。因为正则表达式中是三个字节(我假定你也用 utf8 来编码
代码,如果不是,可以不匹配任何行),而所有输入的行中都含有这三个字节中
的一个,事实上 test.txt 是我精心挑选的,前两个字节都相同的汉字。
2. 不使用 utf8 指令, open 中使用 utf8.
不能匹配任何行。因为输入文件中是汉字,而正则表达式是三个字节。
3. 使用 utf8 指令,open 中不使用 utf8
也不能匹配任何行。因为正则表达式中是一个汉字,而输入文件是一个个的字节。
4. 使用 utf8 指令,open 中也使用 utf8
正确匹配一行。

至于输出的 warning,这确实这是一个小小的 warning,不会影响结果。如果不
想有这个 warning,最好的办法是用 binmode 或者在 open 中指定使用 utf8
layer。或者对于 warning 的字符串用 Encode 模块中 _utf8_on 函数,强制
加上 utf8 flag.


【 在 happierbee (吾生也有涯,而知也无涯) 的大作中提到: 】
: 这个实在不好形容是什么错误呀。改成这个标题好点没?