更佳编程之路: 第 6 章 开发 cfperl,从头开始_VMware, Unix及操作系统讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  VMware, Unix及操作系统讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 3726 | 回复: 0   主题: 更佳编程之路: 第 6 章 开发 cfperl,从头开始        下一篇 
谁是天蝎
注册用户
等级:大元帅
经验:90210
发帖:106
精华:0
注册:2011-7-21
状态:离线
发送短消息息给谁是天蝎 加好友    发送短消息息给谁是天蝎 发消息
发表于: IP:您无权察看 2011-8-25 16:31:58 | [全部帖] [楼主帖] 楼主

引用 Frank Herbert 的一句话,“一切事物之开始是最重要的时刻”。本章是讨论 cfperl 项目的开端。cfperl 项目涵盖了 developerWorks Linux 专区上许多文章所讨论的主题:Perl、cfengine、文本解析以及编写优秀且干净的代码(有关 cfengine 的更多背景知识,请参阅 参考资料)。

在认识到 cfengine(一种极佳的系统管理工具)可以从 Perl 提供的特性中获益,但这些特性却很难作为 cfengine 模块或 C 扩展来实现之后,我决定启动 cfperl 项目。例如,与多数比较自然的 Perl 构造(对我而言)相比,cfengine 的文件编辑能力确实显得有点笨拙。

其实,cfperl 正是我想做的。我认为这个工具是对 cfengine 的增强,而不可能替代 cfengine。以后几章将讲述我对 cfperl 项目一些想法和规划。对于这个项目(目前仍然在做),我是抱着做着玩玩的态度,到目前为止,该项目还没有完成。我的目的是,通过了解我在 cfperl 项目中所采用的方法,您将知道如何将这些方法应用到您自己的项目中。

初步调查

最重要的初步调查是确保不会重复别人的工作,这似乎很明显。如果选择重复开发另一个包已有的功能,则您应该讲出这样做的原因。在开始开发 cfperl 之前,我加入了 cfengine 邮件列表,并留意到人们需要什么。由于已经察觉 cfengine 缺乏灵活性,因此我考虑用 cfperl 作为自己的解决方案。这不等于说 cfengine 不是一个很好的工具,只是对于我和其他人而言,在做一些事情时,cfengine 不具备足够的灵活性。cfperl 的目的是对 cfengine 做一些补充,而不是去做 cfengine 已经做得很好的事情。

我与 Mark Burgess(cfengine 的创建者)一起讨论过 cfperl,我无法找到一种方式来仅用 cfengine 的插件模块体系结构就能实现 cfperl 的功能。这使我确信 cfperl 存在的必要性。



发放许可证

我确定了 GPL 许可证(“通用公共许可证,General Public License”)是 cfperl 的最佳选择。做出这个选择是基于我个人的信仰,但使用 GPL 也有很多真正的好处(请参阅本文后面的 发放许可证和 GPL)。



版本控制

以前,我在几天时间里写过 5000 行的程序。然后,我决定略微改变一下控制流,这花费了一个小时重新处理整个程序。在这之后,我又认识到原来的控制流要更好,所以希望返回到原来的状态。遗憾的是,我一直将所有变更保存在一个文件中,这意味着该程序只有一个版本。我花了一天的时间来纠正这个控制流,然后又在由此而引入的错误上花费了更多时间。

自那以后,对于每个项目,我都使用版本控制。如果您还没有使用版本控制,那么不要犹豫:现在就学习,以后一直用它。就我个人而言,我喜欢 CVS(并发版本控制系统,concurrent versioning system),从一开始(甚至在 GNU 项目托管它之前,GNU 只提供 CVS),cfperl 项目就使用了 CVS。

参考资料这一节包含 CVS 参考资源的其它一些链接。



计划

我不能想象,还有什么能比象 cfperl 这样一个“只为做着玩玩”的项目做计划更简单的事了。显然,没有交付期限的压力,而且,需求也完全取决于我。那么,为什么还要做计划呢?计划迫使程序员以一种特定的方式来思考,使他们有一个目标,并且要交付产品。所以我勉强迫使自己对这个项目制定计划。当然,对于仅仅做着玩的项目,如果您不想遵循计划,也未尝不可。但只要这个产品一天不发布,您就要花功夫去“摆弄”它。

cfperl 发行版 1 的计划:

  • 2001 年 12 月到 2002 年 1 月:需求
  • 2002 年 1 月到 2002 年 2 月:体系结构
  • 2002 年 2 月到 2002 年 7 月:编码
  • 2002 年 7 月到 2002 年 8 月:调试
  • 2002 年 8 月到 2002 年 9 月:建立文档



选择体系结构

cfperl 的体系结构必须类似于 cfengine 的体系结构。毕竟,我要尝试模拟 cfengine 的行为。因此,cfperl 必须解释 cfengine 配置文件,必须至少采用一些 cfengine 所采用的标志,它的文法必须有很大的灵活性,以考虑到 cfengine 文法中的更改。我决定使用 Parse::RecDescent 模块,因为速度不是关键,灵活性才是最重要的。之所以采用 Parse::RecDescent 的另一个原因是曾我使用过它。即使最简单的情况,用 Perl 手工编写文法而不用 Parse::RecDescent 也不是件有趣的做法。开始,似乎很容易,仅仅是一个 while() 循环……但后来会发现有关注释、空格、每个配置部分不同文法等情况,在您还未了解这些之前,您的 while() 循环达到了三页这么长,显然您的脑子无法再适应这种情形。不要让您的朋友在没有文法的情形下,进行解析。

对于其它解析器(包括手工编写的解析器和象 Parse::Yapp 这样的模块),我的经验是它们各自适合于特定的用途,但 Parse::RecDescent 给提供了和 Perl 的最佳的集成。另外,Perl 6 正则表达式和文法非常类似于 Parse::RecDescent 的文法,所以将 cfperl 移植到 Perl 6 也很容易。

对于 Parse::RecDescent ,我决定采用层次式的文法,这意味着要有一个顶级解析器(类似于 C 预编译器),该顶级解析器将具体各个部分分发给各司其职的解析器。例如,该顶级解析器将负责无缝地将外部文件包括到配置中,而针对“class”这一部分的解析器将负责定义类和不定义类。我应该提到 cfengine 具有类的概念:可以定义运行时字符串,也可以不定义它。例如,如果运行在 Solaris 机器上,则 cfengine 定义类 Solaris 。

在内部,cfperl 以 Perl 散列形式存储已定义的和未经定义的类。值可以是 1(已定义的)或 0(未经定义的)。类被复合成复杂的逻辑语句:如果运行在名为 gemini 的 Solaris 机器上,则 Solaris.gemini 将只为 true(或者,如果以其它方式定义了 gemini 类)。 Solaris.!(gemini|jack) 是指只能在名字不为 gemini 或 jack 的 Solaris 机器上执行(或者,如果没有以其它方式定义 gemini 和 jack 类)。我必须为这些复杂的逻辑语句编写单独的解析器。即,也许这部分是我必须编写 cfperl 中最难的部分。

象 cfengine 一样,我使用 AppConfig 模块来处理命令行开关。之所以做这样的选择,是由于我使用过 AppConfig ,同时还由于 AppConfig 的参数解析和 cfengine 参数解析有相似之处。

在接下来向您介绍 cfperl 的几章中,我将向您解释我所做的其它一些体系结构方面的选择。

在接下来的几章中,我将说明 cfengine 没有提供的一些具体功能,而这些功能正是 cfperl 将实现的。简要地说,它们包括:用户管理、更好的文件编辑(这是唯一一个我还将在 cfengine 自身中改进的特性)、crontab 管理和动态执行的 Perl 代码。



发放许可证和 GPL

如果您同自由软件基金会(Free Software Foundation,FSF)签署了版权协议,则 FSF 会保护得到 GPL 许可的软件。而且,如果有人想使用和改进您的作品,则 GPL 确保他们可以这样做,只要他们将对作品的改进也与所有人共享。由于这个原因,有时 GPL 也被称为 viral 许可证。总之,正如在 GNU GPL 许可证自身(V 2)中所列出的,它的关键部分如下所示(关于完整的 GPL 文档的链接,请参阅 参考资料):

  1. 只要包含原始的许可证,使用 GPL 源代码的任何人可以自由地复制和分发它
  2. 由 GPL 许可的源代码派生出的作品也必须遵守 GPL
  3. 程序的二进制文件中必须还包括源代码,或至少给出一种获得源代码的方式
  4. 未经许可,源代码不得经他人重新授予许可证
  5. 对源代码的修改或重新分发意味着接受此许可证
  6. 源代码的接受者自动获得与源代码相关的同样权利
  7. 如果您不能满足有关自由地向他人提供源代码方面的许可证需求,则可以根本不提供给别人
  8. GPL 可能受到地域上的限制(如果在某个国家或地区不能应用 GPL)
  9. GPL 可能会有更新
  10. 即便每个持有源代码版权的人都对此版权达成一致,但也可能出现例外
  11. 没有担保
  12. 没有责任

您可以使用其它许可证,而不使用 GPL。根据与 GPL 的兼容性,可以将这些许可证粗略地分为:

  • 商业许可证 通常用于赚钱,商业许可证保留所有权利,对任何未经许可而查看、修改、分发或复制软件源代码的人,将保证对其惩罚。各种商业许可证在措辞和意图上有很大区别。 
  • 非自由的许可证 这类许可证是指,允许接触到源代码,但不能复制、修改或重新分发。 Apple 公共源码许可证(Apple public source license)就属于这一类许可证。 
  • 基于 FSF 的非自由许可证 一些许可证可以归为这一类,因为它们的意图不明显:通常它们的编写方式使您不能确保您的作品 仍然是自由的。这类许可证与 GPL 有实质性的区别,这使得 GPL 的倡导者认为 Perl Artistic License(请参阅 参考资料)这个体现自由精神的许可证不是自由的。一些开发人员认为 Artistic License 要比 GPL 更自由 ― 大概是因为这种许可证使他们(开发人员)“更自由”地对代码做他们想做的事(包括使代码成为不是自由的)。GPL 倡导者愿意称之为“不太自由的”。从而可能这样概括这场争论:每种许可证的倡导者认为,对于开发人员而言,PAL 要“更自由”,而对于用户而言,PAL 的自由程度要低一些;对于用户而言,GPL 要“更自由”,而对于开发人员来说,GPL 的自由程度要低一些。 
  • 自由的、但与 GPL 不兼容的许可证 这类许可证相当多。例如, IBM 的 Public License 1.0在很大程度上与 GPL 兼容(但其专利权许可证需求使其显得与 GPL 不兼容)。 
  • 自由的、与 GPL 兼容的许可证 XFree86(最流行的免费 X 服务器)所使用的 X11 License就是一个与 GPL 兼容的简单许可证。这类许可证的意图很明显:源代码接受者可以做他想做的任何事 ― 包括封闭该源代码 ― 只要附上许可证文本。




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论