Bin Joy's Blog

There is more than one way to do it...

Perl and Dragon:与大师的会面

当初开始听说 Larry Wall 大神受开源社区 CSDN 的邀请要来中国时还是很激动的,作为一名 Perl 教徒,真没有想到这样就可以见到大神了。

头脑中一直就是 Larry 那张经典的照片的形象,花衬衫,浓浓的胡须。

每当看到这张照片,我脑子里就会不自然的浮想到 Perl 程序员的三大美德:懒惰、急躁、傲慢。

初见大师

于是赶紧去定了 CSDN 2014 开源大会的票,3月30日周六。票也不贵,99块。

话说时间过的很快,转眼就到了那个周末。因为 Larry 排在第二个演讲,本来计划早一点儿赶过去,但是作为拖延症重症患者的程序员伤不起,还是起的有点晚了。。。于是赶紧出门坐车,直奔海淀知春路。

到了签到处,一看基本没什么人签到了,但工作人员还在。于是递上打印的电子票,那姑娘接过去之后说,你来晚了,资料袋已经发完了,送你个名片夹吧。。。我去,我说我可是买票的听众,没道理没有吧?(后来回想自己也许有些不够厚道。)旁边的一小哥赶紧说您稍等,很快就不知从哪里搞了个袋子过来递给我。

其实这资料袋真心没有什么有用的东西,一大堆的赞助商宣传资料,最有用的就是大会日程表了。。。但是拿到了就觉得还是好的。然后赶紧进了会场,会场里还是很惊人的,诺大一会场座无虚席,很多人没有座位的就在最后面或站立或席地毯而坐,所以这会其实基本是无须购票随意入场。台上正在讲的是来自某企鹅企业的第一个演讲者,看来接下来就是 Larry 了。

在一片掌声中企鹅结束了演讲,我们心目中的主角登场了。当然登场前主持人做了简短的铺垫和介绍,因为是开源大会嘛,所以很自然的衔接到开源语言 Perl 上面,然后开始邀请 Larry 上台。印象中 Larry 的步伐缓慢,声音也很低沉,好像开始的时候麦克还有些问题。但是 Larry 还是以幽默的方式开场,这一点倒是觉得在意料之中。当 PPT 上打出拉里-沃尔,Larry 略作停顿,用我们熟悉的那种老外读中文的腔调读了一下自己的中文名字,然后解释到这个名字就是“向里面拉,肥沃你”的意思(pull inside and fertilize you)。我当时想 Larry 的 Perl 语言的确“肥沃”了很多人吧。

于是接下来 Larry 开始以自己参与开源的经历讲起,从开始写的 rn 和 patch 两个主要的程序,到后来如何开始了创建 Perl 这门神奇的语言。因为这次 Larry 是第一次来中国,同时携夫人同行,在介绍开源的过程中,也提到了自己的夫人。这时他的夫人 Gloria 从前排听众席里站起来和大家招手示意,大家也以掌声回应。

Larry 的声音不是很高,但是肯定是为了照顾我们这些国人,语速也不是很快,同时加上 PPT 的提示,所以我基本上磕磕绊绊的还能听懂大意。Larry 的 PPT 也相对简洁,基本是几个词甚至有时是一个词一页,因为 Larry 对汉字有过学习(好像是说因为研究 Unicode 的缘故,当然他也是语言学家嘛),他对单个字或是简单的常用词的意思还是懂的,所以有的 PPT 他会 hack 上一两个汉字,让大家倍感亲切且兴味盎然。

从我入场开始,就陆陆续续的看到一些熟悉的面孔,有同事,也有 Perl 社区的几个小伙伴。在 Larry 演讲结束后,基本已经接近中午了,互相闲聊了一会儿就相约去吃了中饭。

简单的午饭过后,边聊天边回到了会场。下午的会议从上午的一个主会场拆分成了三个独立的会场,分别是不同的主题。大约区分为软件、社区平台和图形游戏。我于是就在三个会场窜来窜去,拣自己感兴趣的话题随意的听下。

于是在会场门外突然发现之前工作人员用的一张桌子后面出现了一个熟悉的身影,对,就是 Larry,旁边坐着他的夫人 Gloria,Larry 手里拿着会场的茶杯在喝茶,和夫人不停的说笑着,仔细看下 Gloria 的手上拿着针,在绣十字绣。。。这时我的心就开始忐忑了,是不是可以凑过去签个名或是合个影呢。但是还是没有勇气走过去。后来发现还是有人过去要签名了,看到 Larry 满面微笑的握手,签字,于是也走了过去,但是到了近前,才发现自己忘带了那本大骆驼,同时包里竟然没有找到一个可以签名的本子。好在看前面的哥们儿是从会场展台那里扫微信换来的日历本上面签的,于是也赶紧去扫了个码换了一本。

再次回来来到 Larry 的旁边,心里本来是想自然的称呼一声 Larry,但是嘴上说出的却是 Mr. Wall 。。。但是 Larry 笑容可掬的站起来和我握手,然后坐下给我签名,Larry 的签名很有趣,他随身带着两个印章,一个上面刻着那句有名的 There is more than one way to do it,另一个就是大家熟悉的大骆驼。两个印章用的印泥也不同,TIMTOWTDT 用的是带有渐变的粉红颜色,而大骆驼的图章用的是深褐色。因为都是激光制的印章,所以大骆驼身上的纹理和 Programming Perl 封面的图案一样精细,密集症患者肯定是看不得的。

签完名,我和 Larry 说能和我合个影吗,于是 Larry 站起身和我站在了一起,我拿出手机让旁边的人帮忙给拍一下。当时我可以说是激动的不行,半天都平静不下来。

正在逐渐平复的过程中看到社区的 Qiang 同学在不远处,于是过去聊天。听我情绪略激动的说刚刚要了签名,Qiang 从包里拿出一个牛皮信封,小心的从里面拿出一张纸条给我看,原来上面同样是 Larry 的签名,同样的印章,不同的是上面有日期,记得应该写的是 2005 年。Qiang 说当时是在洛杉矶参加 PerlConf 时请 Larry 签的,一直收藏着。Qiang 接着建议说可以过去和 Larry 聊天,我当然很想,只是感觉又不知道说什么,但还是过去了。

我们到了近前时就有很多人去签名拍照,所以只能和他夫人 Gloria 聊了起来。Gloria 的头发略显花白,但精气神特别足,在不停的绣十字绣。其实第一眼看她坐在 Larry 旁绣十字绣时,我的大脑里闪现的是武侠小说里面那种深藏不漏的婆婆,总之就是那种遁世高手的感觉。Gloria 也是一名语言学家,但是她应该不会说中文。她说起话来笑的很开心,语速很快,和我们说她正在绣的东西,记得这幅十字绣中心是地图图案,边角装饰有骆驼,上方是她的名字 Gloria。其实 Larry 最早就是以她的名字命名现在的 Perl 语言的,但是后来考虑到有时会引起混淆,所以就用了 Pearl 这个名字,后来干脆去掉 a 这个字母,变成了我们熟悉的 Perl 。感觉 Larry 是很喜欢 Perl 这个名字的,因为在演讲时他说这个名字好,你在搜索时不会像其它语言比如 Python/Ruby 等会出现无关的内容,如果你搜索 Perl 肯定出来的就是 Perl 语言的内容。

我们和 Gloria 聊了一会儿,感觉差不多没有太多可以聊的了,同时 Larry 还在忙着签名合影,于是就走开了。

接下来基本是继续听了一下几个演讲,就结束了这一天的朝圣之旅。

准备 PPT 和礼物

其实在 CSDN 这次活动开始前,北京 Perl 社区小聚的时候大家就知道 Larry 在这次开源大会后会在北京逗留一段,可能会和 Perl 社区的小伙伴儿们又一次见面的活动。

所以开源大会结束的当天晚上,Beijing.pm 微信群里就开始讨论下次见 Larry 的话是不是需要准备一份礼物什么的。有人说既然 Larry 对汉字也感兴趣,是不是可以送他文言的书,什么《说文解字》《唐诗宋词》之类的。有的说送本辞典更好。大家已经在发散思维了。

接下来的几天 PerlChina 应该是和 CSDN 就这个小聚的活动确定好了,时间是4月7日,恰好是清明节放假的最后一天。活动的主题是 Larry Wall + PerlChina Mini Workshop。在 PerlChina 的论坛上面征集向 Larry 提问的问题和演讲主题。

看了一下已经提交的主题基本都是技术方面的分享,虽然自己也想去讲一下,但是纯粹讲技术说实话真心没有什么特别惊艳的东西分享。而且觉得在小伙伴儿们和“教主”的见面会上讲什么也不会引起太多的兴趣吧。后来想 Larry 一直在搞 Perl 文化的传播,同时这次又是他的首次中国行,索性我也讲点中国文化的东西或许也算是刻意的迎合一下整体的氛围吧。

于是就想到《Perl and Dragon》这个主题。这里的 Dragon 肯定是指我们中国龙了,想从 Perl 很强大的角度同时结合一点我们所谓的龙的文化讲点轻松的话题。于是在论坛上提交了一下这个主题。PerlChina 的组织者 Qiang 同学问我这是一个怎样的演讲,我大约说明后,他就回复说主题挺新颖,赶快准备吧。

于是接下来开始梳理思路,同时开始写 PPT。整体还算顺利吧,只是在过程中还是有些没有底气,不知道这样的一个题目是不是合适。但是因为已经提交了,还是尽力准备了。

在4月5日 PPT 基本上完成了。因为在 PPT 中提到了红山文化的玉猪龙,于是就想是不是可以去买个玉猪龙的仿品送给 Larry 做礼物。于是在4月6日去了帝都最有名的仿品聚集地-潘家园市场寻找一枚红山文化的玉猪龙。转了几圈,看到卖这种样式的还是有几家,然后一问价格基本都是几千块,至少也要1000+。完全超出预算,只能作罢。

最后想到 Larry 的两个印章,是不是可以送他一枚闲章。因为据说 Larry 话里话外透露 Perl 6 好像可以见到正式版的曙光了,就想到 rakudo.org 上面的“乐土”二字。于是就刻了篆书的乐土两个字,希望他能够喜欢吧。

Perl Beijing MiniWorkshop 小聚

这次聚会是在4月7日的下午2点开始,地点是朝阳区的一家叫做 happyLatte 的手游公司赞助的场地。提前一小时坐地铁到了,但是这家公司的位置有点偏,竟然找了很久才到,到的时候大家已经在向 Larry 赠送礼物了。PerlChina 社区真的送了一本厚厚的《新华字典》,小伙伴儿都抢着在上面签名,很遗憾因为去了趟洗手间,回来已经签名结束了。。。武汉的 DeepinLinux 公司送给 Larry 一台联想的笔记本电脑,因为上次看到 Larry 演讲时用的笔记本竟然还是 Thinkpad T60 这样一款很老的小黑。当然这台新的笔记本应该也是预装了 DeepinLinux。Larry 的 T60 上面的系统是一个叫做 Linux mint 的发行版,所以不知道 Larry 会不会继续使用预装的系统。当然了,后来用开源大会上赠送的 Deepin 光盘试用了一下这个系统,感觉和大多数的发行版相比在易用性和本地化方面还是不错的。

送完了礼物,接下来 CSDN 的组织者相应的做了简短发言,Larry 就第一个开始演讲了。因为这次是 Perl 社区的聚会,所以 Larry 的演讲完全是和 Perl 有关的。这次他从系统讲起,讲到编程语言。然后从 C 讲到 Perl。首先回顾了 Perl 从最初的版本发展到现在的历史,然后着重讲了一下目前 Perl 6 的现状和他的一些想法。这次 Larry 的 PPT 同样每页的词汇不多,感觉用的有些词更偏一些。比如 Whipuptitude 这个词,可以看这个链接的解释。

Larry 在讲 Perl 的各版本演进的时候,从 Unix 上的主导语言 C 和 Shell 开始,到后来逐渐有 Manipulexity 和 Whipuptitude 的分别。于是以 Manipulexity 和 Whipuptitude 作为维度,以坐标系的图示展示这些语言的在 Unix 系统上渐渐形成的使用使用范围和程度。Perl 从最初版本的出现,融合 C 和 Shell 两者,在 Unix 上面进入到越来越大的影响范围。听到这里,我突然对接下来自己的演讲开始有了些信心,因为这和我准备的 PPT 的一些思路是吻合的,于是继续精神振奋的听 Larry 讲下去。

Larry 最后开始讲到 Perl6 目前的状况,演示了一下 Perl6 的程序,因为目前对 Perl6 我还没有深入的学习,所以也只能大致的听了一下。

接下来的演讲的一共有我们四个,首先是 Achilles 讲了他的开源程序 Transformer,然后是莫言讲了一下快速识别和处理 ip 的技术。然后快轮到我了,因为有些紧张,就站起来手扶着台案做了几个俯卧撑的动作,似乎感觉好了很多。当主持人说到我的时候,就上去了。

因为紧张,整个过程没有控制的特别好。因为 Larry 就坐在最前面,好在从开始 Larry 就和我做了一些互动,所以我渐渐的平复了许多。还记得最有趣的是我说 hi Larry 的时候,他从头上摘下他那顶当天看来主要是作为道具的牛仔帽,做了一个绅士的脱帽致意的动作,显得格外的滑稽有趣。

我估计我的演讲大约最多也就是花了十分钟就讲完了,太快了。分明是 lightning talk ,但对整体的效果基本还是满意的。

下来后记得 Johnny 说你这哪里是演讲,分明是各种 To Larry,至 Larry 嘛,于是只能自嘲地说,我就是一个典型的“狂热的 Perl 教徒”。

接下来陈子做了一个关于微博机器人的演讲,然后是几个真正的 lightning talk。再下来就是签名和拍照环节,全场气氛也进入了一个最高潮。现场小伙伴们的情绪很激动,显得有些嘈杂,Larry 被围在当中,被拉起来拍照,然后签名,所以 Larry 的情绪也是受了影响,开始 high 了起来,那感觉就像是港片儿里的老顽童,像个孩子一样动了起来。于是骆驼印章也开始由平时工工整整的一个骆驼变成了一排骆驼,而且还是有渐远渐隐的效果。接着是下一个,签名然后又是啪啪啪的一排骆驼。我上次在开源大会虽然要了签名,但是因为当时忘了带大骆驼的书,所以今天特意带了大骆驼的上册再请 Larry 给签一下。轮到我的时候,先是把之前准备的那枚“乐土”的闲章送给了他,感觉 Larry 还当时的表情还是很喜欢的样子,然后在给我签名时我说我不要那么多骆驼,一个就够了,于是他工整的盖了一个骆驼上去。

签名结束后,大家开始和 Larry 的各种合影,最后是集体合影。当大家准备给 Larry 准备位置时,Larry 这时还是持续着刚才老顽童的状态,再次出乎我们意料的直接坐在了地上,而且明显是很舒坦的坐在了地上。然后他的夫人 Gloria 坐在了他的旁边。

拍完了照片大家再次回到座位,“添酒回灯重开宴”。Larry 再次来到讲台前,说他也很喜欢中国的龙,所以他 hack 了一下 Unicode ,打印了一长串儿以龍组成的汉字,当然这些汉字我们平时基本是用不到的。然后又打印了biangbiang面的biang字。(关于biangbiang面可以看这里

这时我真的很佩服 Larry 对于汉字从某种角度说要比一般的国人还要了解啊。

接下来 Larry 又讲了一些 Perl6 方面的内容。当他用终端工具回复 IRC 上的消息时,记得好像是 Jonathan(Perl6核心开发者)用中文打出了“下午好”的字样出现在黑底白字的界面,这时突然再次体验那种许久已经没有体验到的现代通讯带来的那种兴奋。Jonathan 因为 2011 年曾来过中国参加 PerlChinaConf,做了一个 Perl6 特性的演讲。记得当时他介绍自己说喜欢 Perl 还有各种啤酒,还展示了他北欧家乡的冻海的照片。所以这次他一定是带着某种久违的情感和大家打招呼的吧。

接下来 Larry 让大家讲讲如何和 Perl 结缘的故事,为何会喜欢上 Perl。小伙伴们也是踊跃的发言,Larry 则静静的听大家讲。等大家都讲完了,主持人Qiang宣布这次活动也结束了。同时晚上会有和 Larry 的聚餐活动,可以自愿参加。

晚餐

晚餐是在一家老北京风格的餐馆,我们一行包括 Larry 夫妇在内大约十个人左右。

餐厅很干净,我们在二楼的一个房间里坐下,大家开始点菜。据说 Larry 来到帝都还没有吃过烤鸭,所以先点了烤鸭,我点了清蒸鲈鱼。

大家于是东一句西一句的聊了起来。Larry 说到了要写关于 Perl6 的书因为一些原因可能要推迟,说到了他自己德裔的血缘让我不禁想到难怪会有 Perl 这门语言精巧而复杂的设计和实现。当讲到了他的几个孩子时明显的感觉到脸上洋溢着那种幸福感。而有时他们夫妇两个会同时说出一样的字句时,你更会羡慕这对伴侣的心有灵犀。

当讲到他们居住的加州时明显会感觉到他们作为加州人的自豪感,大家还询问了加州的房价并和帝都的做了比较。。。

我注意到 Larry 夫妇的筷子用的都很顺畅,原来他们也经常去加州的中餐馆或是日本餐馆。Larry 还说中餐馆会同时提供筷子和刀叉,但是日本餐馆只提供筷子。我发现他们吃中餐的方式还是有些西式的吃法,就是会把菜分到自己的碗里,然后再吃。而且我注意到一个细节,我们如果夹菜不小心掉在桌子上基本都不会去吃了,Larry 则不然,会毫无顾忌的夹起来继续吃。

当烤鸭上来时我被选中演示一下吃法,所以就直接用手抓了面饼卷了起来,大家起哄喊让我手不要抖,我其实真的没有抖,因为和这群人在一起我没有感觉到距离,自然心里也没有什么恐惧的。

当鸭架做的汤上来时,Larry 问他夫人要不要,他夫人表示已经吃好了。Larry 尝了一下感觉汤的味道还不错,于是就给他夫人盛了一碗放到面前,让我们真的感觉到他们的感情很好。

Larry 喜欢日本的动漫,也一直在学习日语。于是和他聊了几句关于日语的话题,讲到了音读和训读。之后在座的各位还是按顺序做了大约的介绍。我说自己一般不好意思说自己是英语专业,因为感觉自己的英文不是很好。Larry 说其实还好了。当我说除了学过日语还学过韩语时,他就对我说了一句韩语的你好。

这时时间到了九点多,大家也聊的差不多了,所以开始一起起身离开。

当我们几个和 Larry 先下楼在门口等其他人时,外面夜色已深,整条街灯火通明。北京9点多钟其实时间还早。Larry 抬起头对着对面的一处建筑上面亮着灯的招牌嘴里轻轻的叨咕着,原来他是在读上面的汉字。

一次很开心很难忘的聚会。

最后

这篇文章从这次聚会后就在酝酿,直到今天才写好,时间已经过去好几个月了。希望给那些当初想见但是没能见到 Larry 的和我一样带有某种情怀的 Perler 尽可详细的介绍这次“朝圣”的经历,当然因为有些细节可能也会存在不准确的情况,所以希望知情人可以纠正我的疏漏。同时文中提到了一些人的姓名,如果有任何隐私的问题,可以通知我,我会第一时间修改。

另,文中图片来自社区的小伙伴儿,这里只是借用,版权归其主人。

资源

我的演讲 PPT : Perl & Dragon

相关内容

程序员杂志采访 Larry 的文字版:Larry Wall:我的目标永远是让人开怀

[翻译] 宫川达彦的 Perl UTF-8 闪电教程

原文链接: Perl UTF-8 crash course

我还是常常看到 Perl 程序员对于 “Perl 以非常简单(有时 bug 频出但容易修复)的处理 Unicode 字串的方式” 理解不够的情况出现。

我坦承六七年前我对此也有着同样的误解,所以不愿看到别人再重蹈覆辙。那就赶紧拿出五分钟时间,忘记你所知道的一切,学一下这个简单的教程吧。

一) print($a, $b) 和 print($a . $b);

让我们暂时忘却 utf-8 标识、操作符重载,还有其它所有那些疯狂的东东。

当你看到 print($a, $b) 和 print($a . $b) 时,你觉得它们打印出的内容会一致吗?

1
2
3
4
5
> perl -le 'print "foo", "bar"'
foobar

> perl -le 'print "foo". "bar"'
foobar

它们会打印出相同的内容,否则就会让人疑惑不解。这一点 Perl 和你所见略同。

二) 默认 Latin-1 编码

然后,你再运行一下这个试试:

1
2
3
4
5
6
7
8
9
a) > perl -Mutf8 -MEncode -le \
        'print "テスト", encode_utf8("テスト")'
Wide character in print at -e line 1.
テストテスト

b) > perl -Mutf8 -MEncode -le \
        'print "テスト". encode_utf8("テスト")'
Wide character in print at -e line 1.
テストãã¹ã

哇,这次你向逗号版本和句点版本传递了相同的参数,但得到不同的结果。这让人疑惑不解,每一个都有可能是错的。你觉得哪个是正确的行为呢?

一些砖家也许会略过细节,说:“噢,utf-8 标志位和自动转换在 b 中起了作用。所以这是 bug 所在。” 如果你也这么认为,看来你对 perl 解释器非常了解,以至于适得其反。或者可以直接说,你错了。

看到控制台输出的那堆乱码,是否说明 a) 是 Perl 解释器的“正确行为”?

错,b) 才是正确的行为。因为后半部分 encode_utf8(“テスト”) 产生了9字母字节的字串给 perl 解释器,perl 解释器以为它是以 latin-1 编码的。因此它在控制台的输出是正确的(尽管看上去像垃圾)。Perl 字面上是以 latin-1 为默认编码进行处理的,这正是你想要的。

a) 代表了 Perl 的 bug(由于历史原因造成的),它根据参数的字符范围而改变了默认输出的编码格式。

1
2
3
4
use utf8;
use Encode;
print "テスト";               # <- 输出宽字符(Wide characters),以 UTF-8 编码打印
print encode_utf8("テスト")'; # <- 输出 Latin-1 字符,以 Latin-1 编码打印

perl 解释器对于产生了完全相同的八位位组(octet)序列以不同的编码打印时,结果是完全不同的字符串。

perl 解释器的这个行为可以通过使用 binmode 指定输出编码的格式來修正,命令行可以通过加上 -C 实现。 (主要是对 STDOUT 使用 utf8 编码):

1
2
3
4
5
6
7
c) > perl -C -Mutf8 -MEncode -le \
        'print "テスト", encode_utf8("テスト")'
テストãã¹ã

d) > perl -C -Mutf8 -MEncode -le \
        'print "テスト". encode_utf8("テスト")'
テストãã¹ã

这下逗号版本和句点版本都“正确地”显示了字符。

三) Latin-1 和 ASCII

现在我们退一步,看下没有宽字符时会打印出什么。

1
2
3
4
5
6
7
e) > perl -Mutf8 -MEncode -MData::Dump=dump -le \
        'print dump("テスト"). encode_utf8("テスト")' 
"\x{30C6}\x{30B9}\x{30C8}"テスト

f) > perl -C -Mutf8 -MEncode -MData::Dump=dump -le \
        'print dump("テスト"). encode_utf8("テスト")'
"\x{30C6}\x{30B9}\x{30C8}"ãã¹ã

这次同样以相同的代码(都是句点的方式),打印相同的变量,然后在输出时你得到了不同的结果。

正如我们前面所见,perl 解释器以 latin-1 编码打印 latin-1 字符串是一个 bug(例子e),在 f)中使用 -C 参数得到的是正确的结果。

总结

如果你向一个文件句柄打印八位位组而不指定任何一种编码格式(如本例中的 STDOUT),这时你还以为原始的编码会被保留,那你就是想倚重 perl 解释器的 bug。因为 perl 解释器的 bug 以及输出和终端编码不匹配的原因,碰巧你会看到原始的八位位组,看到它们出错了。

Perl 以 latin-1 为默认编码处理字符串。所以不管爽不爽,你都得这么做。这意味着你要告诉 perl 解释器八位位组是用哪种编码格式做的 decode。

latin-1 到 utf-8 的自动转换并非 bug 所在。自动转换是预期的动作,恰是你想要的。避免自动转换的思路既非是通过避免字符串连接(见例子 a. 使用逗号,而没有使用句点),更不是通过跳脱其它的变量(见e)。这些只是隐藏了问题所在,而非解决了问题本身。

自动转换会导致所谓的 “bug” 的唯一情形是,当你真正想向一个原始的文件句柄中打印字节流时。举个例子,当你创建了一份 JPEG 的二进制数据,打印到一个本地文件中。如果你创建了完整的 JPEG 数据,包括在它的 EXIF 区域的宽字符,perl 解析器突然以为这是 latin-1 字串而把它转换成 UTF-8 数据。

因为没有办法告诉 perl 解释器给它的字串其实是八位位组而非字串(我真希望能有办法),所以你不得不确认对所有打印到原始文件句柄的字符进行了正确的编码。混入没有正确编码的宽字符的话,问题在你,而非 perl 解释器。

如果你没有正确处理,就会看到 “Wide characters in print…” 的警告。出现这个时肯定是有原因的。

另见:

很巧合,Dave Cross 遇到了类似的讨论,在他的博客发了这篇《Unicode and Perl》简化版的小测试。 (译注:可以看我的译文:查看

[翻译] Unicode 与 Perl

Perl Weekly 第109期的主题是 “Unicode and Perl”,其中推荐了两篇关于 Unicode 的博文。一篇来自 perlhacks.com 的 Dave Cross,另一篇则来自重量级人物 Tatsuhiko Miyagawa(宫川达彦)。非常有趣的是两个博主都在博文最后引用了对方博文的地址。

这两篇博文虽说都是关于 Unicode 的,但是风格不尽相同。Dave Cross 的文章很短,就是给出了一个快速测试题,并称几天后会给出相关答案。但宫川的文章则是相对详细的示例分析和总结。

其实笔者在 2011 年自从读了 Effective Perl Programming 一书中关于 Unicode 的部分后感觉对 Perl 的 Unicode 问题已经明晰了很多,但是在日常编程中偶尔也会被编码问题困扰。比如最近在使用 Dancer 的过程中就遇到此类问题。看来编码这个问题一定要彻底搞清楚才可以。所以在阅读学习两篇博文的同时尽力做了翻译,以便有这方面学习需要的同学可以更快的理解。

两篇文字都会翻译,先翻译 Dave Cross 这篇短的。

正文

原文地址:http://perlhacks.com/2013/08/unicode-perl/

在过去几天我就遇到好几拨讨论,很显然有些人对于 Perl 如何处理 Unicode 还不甚了了。这篇文档条理清晰内容详实(这里还有一个不错的教程),但不知何故,人们仍旧会陷入误区。

下面是一个快速小测验。你能详细的说明这四个命令行程序的来龙去脉吗?为了取得一个好的绩效考核,在我们的代码中应该效仿哪一个呢?

1
2
3
4
5
6
7
8
$ perl -E'say "£"'
£
$ perl -Mutf8 -E'say "£"'
$ perl -C -E'say "£"'
£
$ perl -C -Mutf8 -E'say "£"'
£

为了统一环境,假设系统 locale 都设置为 en_US.UTF-8。

几天后我会公布详解。

更新:巧合的是, Miyagawa 在他的 blog 也发了一些非常相似的内容

译注:可以看我的译文 查看 另我查看了 perlhacks 的博客,并没有公布答案,其实看了宫川达彦的那篇后,也许你就不纠结他没有公布答案了:)

Dancer2 试用小记

安装 Dancer2

注:本部分参考 Dancer2::Manual

安装 Dancer2 的方式和安装其它 Perl 模块没有什么区别,使用 cpan 命令或是源码安装的方式都可以。

1
perl -MCPAN -e 'install Dancer2'

当然如果你已经在机器上安装了 cpanm 这个模块你可以直接 cpanm Dancer2 就可以了。如果没有安装 cpanm 你在类 unix 机器上可以使用下面这行命令方便的使用它:

1
wget -O - http://cpanmin.us | sudo perl - Dancer2

如果你没有 root 权限这里不要写 sudo 。

使用 Dancer2

Dancer2 没有它自己的生成器,要使用 Dancer1 的 dancer 命令来生成应用的目录结构。

1
dancer -a myapp

然后进入到 myapp 这个目录,执行:

1
for f in $(find {lib,bin} -type f) ; do cat $f | sed -e 's/Dancer/Dancer2/g' > $f.2 && mv -f $f.2 $f;chmod +x $f; done

这样就会将文件中的 Dancer 修改为 Dancer2。可以直接启动:

更新:现在 Dancer2 已经具有自己的生成器了,安装好 Dancer2 后,直接 dancer2 -a appname 就可以生成一个项目了。

1
./bin/app.pl

也可以使用 plackup 命令启动它,如果你已经安装了 Task::Plack 这个模块的话:

1
plackup ./bin/app.pl -p 5000

这样在浏览器输入本地地址和相应的端口就可以访问到 Dancer 的默认页面。

为什么使用 Dancer2

直接引述 Dancer 作者的话:减少了和其它模块的命名空间碰撞,引入 Moo 的威力,框架本身代码更少但性能更高,而且如果你想深入研究 DSL 的话,Dancer2 背后提供的是一个很强 OO 特性的 API。

注意点

  • 编码问题:Dancer2 的要在配置文件中指定模板的编码,否则会出现乱码的情况,尤其是我们使用中文。比如我在模板中设置使用 UTF-8 的编码,配置文件也写了 charset: UTF-8 这样的指定,但是页面的中文还是乱码,Dancer2::Cookbook 中说还要指定模板的编码,这和 Dancer1 还是有些不同的。正确的设置是这样的:
Dancer2 encoding configurationDancer2 CPAN DOC
1
2
3
4
charset: UTF-8
engines:
  template_toolkit:
    ENCODING: utf8
  • 依然是编码问题 – –||| : Dancer 的 to_json 函数在遇到汉字时前端会乱码,但使用 JSON 模块的 to_json 就不会,具体原因还待深入 。

  • 在开发 爱微链 过程中发现,默认模板 Template::Simple 在遇到多层数据结构时可能不能正确解析出想要的数据,所以建议即使是开发过程中也还是先设置好用 TT 吧。