几年前,Unix哲学的支持者David Korn在Slashdot的一次采访中指责Perl程序员编写了单片Perl脚本而没有通过管道,重定向等使用Unix工具包."Unix不仅仅是一个操作系统".他说,"这是一种做事方式,外壳通过提供使其起作用的胶水起着关键作用."
似乎提醒可以同样适用于Ruby社区.Ruby具有通过popen,STDIN,STDOUT,STDERR,ARGF等与其他Unix工具协同工作的强大功能,但似乎越来越多,Rubyists选择使用Ruby绑定和Ruby库并构建单一的Ruby程序.
我理解在某些情况下可能存在性能原因导致单片并在一个Ruby进程中执行所有操作,但是肯定有很多离线和异步任务可以通过与其他小程序一起工作的Ruby程序很好地处理这种方法具有所有优点,在Unix方面很好.
也许我只是遗漏了一些明显的东西.Unix哲学今天仍然与10年前一样重要吗?
Nor*_*sey 19
管道和简单工具的Unix哲学是用于文本的.它仍然具有相关性,但可能与以前不相关:
我们看到更多的工具,其输出设计不易被其他程序解析.
我们看到更多的XML,通过过滤器管道文本没有特别的优势,而正则表达式是一种冒险的赌博.
我们看到了更多的交互性,而在Unix管道中,信息只向一个方向流动.
但是,虽然世界已经发生了一些变化,但我仍然赞同科恩的批评.无论语言是什么,创建无法与其他程序互操作的大型单片程序绝对是糟糕的设计.规则与以往一样:
记住你自己的程序的输出可能是另一个程序的输入.
如果您的程序处理单一类型的数据(例如,学生提交的代码的性能,这是我上周一直在做的),请确保对该数据的输入和输出使用相同的格式.
为了与现有Unix工具的互操作性,输入和输出应该是ASCII和面向行的.许多IETF Internet协议(SMTP,NNTP,HTTP)都是很好的例子.
考虑用shell管道编写几个与现有程序相连的小程序,而不是编写一个大程序.例如,一段时间后,xkcd博客有一个可怕的管道,用于查找字谜/usr/share/dict/words.
通过将交互式shell作为脚本逐步编写,逐步处理shell脚本.(我使用ksh但任何与POSIX兼容的shell都是合理的选择.)
总之,有两种高度相关的重用代码的方法:
编写通过shell管道(Unix)连接时很好的小程序.
编写完全吻合时由连接小库import,#include,load,require,或use(红宝石,C++ STL,I2C接口和实现方式,并且许多其他的).
在第一个范例中,依赖结构很简单(总是线性的),因此易于理解,但是你可以表达的内容更加有限.在第二个范例中,您的依赖结构可以是任何非循环图形 - 更具表现力的功能,但其中包括创建无偿复杂性的能力.
这两种范式仍然具有相关性和重要性; 对于任何特定项目,您选择哪一个项目更多地与您的客户和您的起点相关,而不是与范例的任何内在优点相关.当然,它们不是互相排斥的!
我的投票是肯定的.主观但优秀的编程问题.
在我们为保险公司重新编写大规模打印输出程序的时候,这只是个人轶事.我们被shell中的"编程"顾问骂了一顿.我们已经意识到它是如何断开连接的,语言太过完全不完整.
也许.
突然之间,多处理器的英特尔Boxen变得司空见惯,而fork()并没有真正表现得如此糟糕,因为在新的应用时代,人们总是被警告(想想VB日).批量打印程序(查询数据库,转换为troff输出,然后转换为PostScript msgsnd,然后关闭到LPD数十万个队列),与所有系统完美匹配,并且在VB运行时更改时不需要重写.
对于你的问题: 我和Korn先生在一起,但这并不是Perl的错,Perl程序员认为Perl足够了.在多进程系统中,它可能已经足够了.
我希望Ruby,Perl,Python和(喘气)甚至Java开发人员都可以在shell管道中保持优势.隐式扩展和接口,职责分离和模块化设计的开发理念具有内在价值.
正确地接近我们的大规模处理单元,Unix哲学可能会再次获得成功.