首页 | 资讯动态 | linux基础 | 系统管理 | 网络管理 | 编程开发 | linux数据库 | 服务器技术 | linux相关 | linux认证 | 嵌入式 | 下载中心 | 专题 | linux招聘 | HR | 镜像
OKLinux中文技术站
·设为首页
·加入收藏
·联系我们
系统管理: 中文环境 系统管理 桌面应用 内核技术 | Linux基础: 基础入门 安装配置 常用命令 经验技巧 软件应用 | Linux数据库: Mysql Postgre Oracle DB2 Sybase other
网络管理: 网络安全 网络应用 Linux服务器 环境配置 黑客安全 | 编程开发: PHP CC++ Python Perl Shell 嵌入式开发 java jsp | PHP技术: PHP基础 PHP技巧 PHP应用 PHP文摘
搜索中心 Linux招聘 Linux专题 Apache | Linux相关: 硬件相关 Linux解决方案 Linux认证 企业应用 其它Unix | 相关下载: 资料下载 参考手册 开发工具 服务器类 软路由 其它
 技术搜索:
会员中心 注册会员 高级搜索  
  → 当前位置:首页>编程开发>perl>正文

功能丰富的Perl:JustAnotherPerlHacker

http://www.oklinux.cn  2007-02-09  oklinux收集整理   会员收藏  游客收藏  【 】 
您查看的文章来源于http://www.oklinux.cn


  JAPH:“Just another Perl hacker”
  据我们所知,JAPH 格式是在二十世纪九十年代由 Randal Schwartz 推广的(好几处信息来源都同意这个说法)。今天,JAPH 到处可见,它们是由该流派的那些不知疲倦的艺术家们制作的,比如 comp.lang.lang.perl.misc 新闻组的 Abigail。
  
  下面的讨论中我们将分析 CPAN (请参阅参考资料)上的规范列表中的一些 JAPH,它们适合初级到中级 Perl 程序员。我在这里会对各种技巧作简单的说明,但是有兴趣的读者还是应该参阅 Programming Perl,第三版(请参阅参考资料)来进一步学习。
  
  为了精确地支持这里所给的示例,您的系统中必须安装有 Perl 5.6.0。最好您还安装了最新的(2000 或者更新版本)主流 UNIX 系统(Linux、Solaris、BSD)。尽管这些示例也许能在老一点的 Perl 和 UNIX 版本甚至是其它操作系统上运行,您还是应该考虑一下如果它们运行失败这样需要解决的问题。每个 JAPH 都以规范列表的格式显示,带有一个日期和作者属性。
  
  优良的
  在开始讨论更丰富的内容之前,我们先来看看 Randal Schwartz 在 JAPH 的早些时期编写的四段简单有趣的代码。我们下面的第一个示例证明了并不是所有的 JAPH 都是要晦涩难懂的,有一些甚至是很容易看懂的。
  
  清单 1. 一个简单的 true 条件句
  
  Date:     18 Jun 90 15:53:11 GMT
  From:     [email protected] (Randal Schwartz)
  print "Just another Perl hacker," if "you can't think of anything better..."
  
  在清单 1 中,既然字符串不为空,if() 语句的值就始终为 true(只有空字符串“”、字符串“0”,数字 0 或其等价的表达形式,或者不定义时其值才为 false)。因而,将一直执行打印语句。
  
  清单 2. 使用 Printf
  
  Date:     15 Jun 90 22:06:24 GMT
  From:     [email protected] (Randal Schwartz)
  printf "%s %s %s %s%c", 'Just', 'another', 'Perl', 'hacker', 44
  
  清单 2 是另一个早期的样本,它使用 printf() 的函数来产生所需的输出,这也证明了如果您愿意的话,Perl 看起来也可以象 C 语言一样。
  
  在清单 3 中 Schwartz 开始玩花招了。现在我们给 print() 一个重新排列过的数组,然后将这个数组打印出来,单词之间有空格($ 是一个变量,它告诉 Perl 在一次打印所有数组元素时在元素之间应该放什么东西)。
  
  清单 3. 重新排列数组
  
  Date:     5 Jun 90 19:07:58 GMT
  From:     [email protected] (Randal Schwartz)
  $,=" "; print +("hacker,","Just","Perl","another")[1,3,2,0];
  
  数组前面的 + 使 print() 把紧随其后的东西当做一个单独的参数(在本例中因为有圆括号,所以是数组),而不是把圆括号当做是函数调用。换句话说,我们避免了以下情况: print ('a', 'b')[1]; 其中,print() 把‘a’和‘b’当做它的第一个和第二个要打印的参数,然后 Perl 就不知道 [1] 是用来做什么的了。
  
  清单 4 是最早的有记录可查的 JAPH,还有点别出心裁,使用了 split()、sort() 和 grep():
  
  清单 4. Sort 然后 grep
  
  Date:     6 Feb 90 22:31:17 GMT
  From:     [email protected] (Randal Schwartz)
  print grep(s/^\d+(.*)/$1 /, sort(split(/ /,"8hacker, 4Perl 1Just 2another")));
  
  首先,我们把起始字符串分割成四个元素:“8hacker,” “4Perl” “1Just” “2another”。
  然后我们排序 ― 缺省情况下是按字母数字顺序 ― 得到: “1Just” “2another” “4Perl” “8hacker,”。
  
  注意 “10Just” 也应该排在 "8hacker" 的前面 ― 这不是数字排序。
  
  排序后的列表被传递到 grep(),它将每个元素开头的所有数字都去掉,并在剩下的部分后面加上一个空格。结果是: “Just ” “another ” “Perl ” “hacker, ”。
  
  最后,在这个列表上调用 print(),逐字逐元素打印。
  
  糟糕的
  看够了 JAPH 的优点后,现在让我们来看看它真正“糟糕到极点”的地方。良好的 JAPH 还有循序渐进的教学作用,糟糕的 JAPH 却让您的思维混乱得象椒盐卷饼一样。当您盯着一段 JAPH 冥思苦想十分钟却只能头疼时,您就知道这个 JAPH 是糟糕的了。
  
  清单 5. 代替和计算
  
  Date:     26 Mar 90 16:20:37 GMT
  From:     [email protected] (Raymond Chen)
  $_='x"Not ";"x\"another \";\'x\\"perl \\";x\\"hacker,\\"\'"';s/x/print/g;eval eval eval;
  
  这里举例说明的一个普通的技巧是用另外的单词来代替原有的一个单词,然后再计算输出(实际上,在您进行这个步骤时正在建立 Perl 代码)。上面的示例中,每一个"x"都被换成了"print"。您还应该懂得 Perl 中的引用规则。Perl 在那个字符串中计算之后看到的是:x"Not ";"x\"another \";'x\"perl \";x\"hacker,\"'"(在 s/// 命令前面加上一个 print() 来察看这一点。)
  
  字符串以一个单引号开头,所以它也必须以一个单引号结束。如果您往前面找单引号,就会发现有两个单引号转义了(带一个反斜杠),第三个才是真的。
  
  现在,运行替换(在 s/// 命令后面加上一个 print() 自己去看结果):print"Not ";"print\"another \";'print\"perl \";print\"hacker,\"'"
  
  接下来是我们的命令了。为什么在这里要运行三个 eval() 命令,而不是仅仅一个呢?仔细看一下。第二个 print() 是在字符串里面的,并不会被第一个 eval() 计算。但第一个 eval() 会返回计算过的第一级字符串:print"another ";'print"perl ";print"hacker,"'。它将打印出“Not”。为什么第一个 eval() 不返回字符串的第一部分?因为 eval() 只返回计算过的最后的东西。用“print eval”代替“eval eval eval”作为最后的语句,看看这样操作的效果如何。
  
  第二个 eval 是做什么的呢?它是用来计算第二个,而不是第三个或第四个 print() 语句的。如果您观察一下就会发现它们两个都是在一对单引号内的字符串里的。第二个 eval 会返回含有第三个和第四个 print() 语句的字符串,留下刚刚打印了“another ”的那个语句。所以第二个 eval 将返回:print"perl ";print"hacker,"
  
  第三个 eval 会运行那两个 print() 语句来结束这段 JAPH(奇怪的是,它会打印出“Not another perl hacker,”)。
  
  正如您所看到的,分解一段糟糕的 JAPH 是要花坏闶奔涞摹<词故窍笪颐歉詹沤庖氲哪敲醇虻サ亩?鳎?詈蠖加泻眉父龈丛拥牟愦巍?
  
  让我们来分析另一个糟糕到极点的 JAPH :
  
  清单 6. Abigail 的天书
  
  #Abigail
  $_ = "\x3C\x3C\x45\x4F\x54"; s/<  Just another Perl Hacker
  EOT
  
  清单 6 看起来也象是一段简单的 JAPH。为什么?字符串就在那里 ― 有什么神秘的地方?其实,Abigail 风格就是以一种新的方式来使用您以前所见过的东西。例如,在这里,给操作符 s/// 加上了修饰符“e”。这样就让它在进行替换之前计算右边的表达式。这样一来,“<  
  编码的 $_字符串最后包含“<  
  编码过的字符串和看似简单的替换是 JAPH 的支柱。尤其是替换,它可以用新的令人惊奇的方式进行,您会发现在您自己的代码中这些方式很有用。
  
  下面是 Abigail 的另一段如恶魔般让您绞尽脑汁的 JAPH:
  
  清单 7. Abigail 解释的原型
  
  #Abigail
  perl -wle 'sub _ "Just another Perl Hacker"; print prototype \&_'
  
  理解这段 JAPH 需要一定的使用原型的知识。请参阅“perldoc -f sub”和“perldoc -f prototype”文档来了解这是怎么一回事。基本上,这建立了一个新的函数,它名为“_”,没有函数体,但带有一个“Just another Perl Hacker”的原型。
  
  如果您看了 Programming Perl,第三版(请参阅参考资料)关于原型的实际章节,您会发现原型不能是字符串。Abigail 很随便地忽略了这个事实(因为这个函数永远都不会用到),然后打印出了无效的原型。
  
  这样合法吗?可能吧,因为它并不引起程序崩溃。这样疯狂吗?只有一点点。还有很多更疯狂的方法,但这一种至少还证明了在定义函数时原型的合法性不会受到检查。它还示范了我们可以定义一个名为“_”的函数 ― 这种方法您不应该经常使用,因为它会和内建的“_”操作符冲突。
  
  难看的
  我们看过了良好的和糟糕的 JAPH,所剩下的就是难看的 JAPH 了。这些怪兽被精心打造,就是为了让人们畏惧然后到处找药吃,它们定义得太丑陋了。
  
  下面这一段 Kickstart 编写的 JAPH 您应该送给对您非常重要的另一半(不包括家里的宠物)。注意,称其为一段难看的 JAPH 是不止一个原因的 ― 四行的限制被远远的抛在一边。
  
  清单 8. 燃烧的心
  
  #Kickstart from http://www.perlmonks.com/
  #note: a slight valentine variation :)
  
     $LOVE=        AMOUR.
    true.cards. 




上一篇:功能丰富的Perl:遗传算法仿真多细胞机体   下一篇:用Perl写不刷屏的聊天室原理分析

收藏于收藏夹】 【评论】 【推荐】 【打印】 【关闭
相关文档
·功能丰富的Perl:遗传算法仿真多细胞机体
·用Perl写不刷屏的聊天室原理分析
·善用PerlDateStructure和reference
·用Linux下脚本Perl连接SQLServer
·Linux下Perl的经典用法:读入单个记录
·功能丰富的Perl
·Linux环境中的Mod_perl编程介绍
·ActivePerlPerlIS.dll远程缓冲区溢出漏洞
·功能丰富的Perl:用Perl保存
·功能丰富的Perl:有趣的Ion窗口管理器
·功能丰富的Perl:用于系统管理
·功能丰富的Perl:编写说英语的Perl程序
·功能丰富的Perl:xinetd程序用于系统管理
·功能丰富的Perl:Perl6语法和正则表达式
·Perl的经典用法:用Sysopen()进行控制
·吸引C和Java程序员目光的Perl5.6
发表评论
密码: 匿名评论
评论内容:

(不超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规)
 
  最新文档
·Linux下安装Perl脚本语言的方法
·以非超级用户身份安装mod_perl
·优化Perl榨取代码的最大性能
·功能丰富的Perl:Perl自动化系统管理
·使用Perl/Tk把GUI加入服务器编程
·CJavaPHPPerlPython的程序代码美化工具
·改良的Perl:程序员面向Linux的设置
·Perl的经典用法:用Open()函数打开文件
·功能丰富的Perl:轻松调试Perl的技巧
·功能丰富的Perl:Perl用于实现遗传算法
·Linux使用基本知识:编写简单的perl
·功能丰富的Perl:用Perl读写Excel文件
  阅读排行
·使用Perl自动化UNIX系统管理
·功能丰富的Perl:用Perl读写Excel文件
·利用Perl列出系统环境变量清单范例
·Perl的经典用法:用Open()函数打开文件
·Linux下安装Perl脚本语言的方法
·优化Perl榨取代码的最大性能
·用Pear加速PHP程序开发
·怎样从Perl中调用C库里的函数
·Linux使用基本知识:编写简单的perl
·功能丰富的Perl:轻松调试Perl的技巧
·在Perl中使用SendMail发送邮件
·功能丰富的Perl:编写说英语的Perl程序
·用Perl写不刷屏的聊天室原理分析
·吸引C和Java程序员目光的Perl5.6
·改良的Perl:程序员面向Linux的设置
网摘收藏: