抛掉重用的幻想,好使就行:用脚本生成脚本的例子
阿于同学说过,合肥同学不懂什么是"好使",所以,先解释一下。"好使"可能是东北方言,大意是 可用,能工作,趁手。
今天讲的是在用脚本生成脚本中,可以对付到什么程度。
当年写用vba自动判卷的时候,某张同学说"这个要是再这么一下,那就更好了",小韩老师说"唉呀大姐 (我记得是这样说的,小张比小韩要小) ,你是要开发个工具,不是产品。"
韩老师说的话大抵容易懂,而深刻,对我颇有教益,这一句就是。代码可以重用到什么程度,给用户提供多大程度上的方便 (友好之类的),在工程中,不仅要看未来和追求,也要视为一个急功近利的短期行为。
如果我们在VBA判卷上做得那么完美的话,当年我跟偶像多半个下午判完全部试卷的传奇故事就不会发生了。我们可能今天还在追求某个完美的细节。我记得当年李老师质疑过我的判法,"你这么判,要是那么答,不就错了也得分么?"我答,"是啊,不过换成人判,比如你,就能那么认真了?"
写程序,我们要的只是比没程序更好,不是最好。"最"这种事,只存在于当今的媒体、人民的幻想及前后的之中。对不起,错了,语言不仅是"最",而且是"最最"。需要补课的同学请自行阅读参考书,这里不展开了。
有时候,追求完美的重用--对未来的无比重视--会让我们失去今天。当然,失去今天也就没有未来了。
比如,年轻男女经常讨论的问题,类似于"以后到底谁刷碗"啊这样的。重用这和这个类似。事实上,以我们的年轻和技术之浅薄,大多时候,因为没有足够的经验,我们根本无法预测未来会如何发展。重用是什么?重用是在*未来*被自己或别人*再次*使用。咱们这点破技术,知道未来如何再次使用这些代码么?
有同学说,"书里说了"。呵呵。
书归正传。用脚本生成脚本,一看这题目,不少同学就会想到编译原理啥的,还有同学想到了lisp里的宏。我说的不是这些高级题目,而是极其朴素的刚刚能对付得过去的手段。
1. 所谓朴素
所谓朴素,就是尽可能不使用和依赖高级的技术。比如,我到C++中的 flowcontrol的时候,讲到循环执行,给过这样的例子:
请输出从1到5的数字。
同学们给出的答案都是:
for(int i=0;i<5;++i)
{
printf ("%d\n", ++1);
}
当然,漂亮。
我的一个答案是这样的:
printf ("1\n");printf ("2\n");printf ("3\n");printf ("4\n");printf ("5\n");
我看到了,得有超过半个班级的同学对我的写法嗤之以鼻。这代码太烂了,马上就会有人指出,"要是输出到100呢,要是输出从8到20呢。"
我的代码的缺陷,缺乏重用性,数量大了不好改。一,谁说我准备重用了呢?我们一看到别人的问题,往往就要预想提问者的动机,有时甚至解读过度。中层对上层的解读,往往如此,下层就受了苦。二,数量大的时候,其实也简单,我可以在excel按ctrl拉鼠标,得到数字序列,然后再把这一列粘到C代码里。
之所以能这么对付,是因为,我也可以假设这段代码只用一次,而且只被我一人使用。
2. 例1,跟牛同学的讨论
前几天跟刘同学一起破解了个软件,我的解法暴力而有效,刘的解法更好,极其优雅。可惜现在似乎还不宜显摆具体内容。不过,后续与牛同学的一些交流可以在此讨论一下。
我为牛同学分配的任务是,把这好几千个文件的名字改成符合某个算法要求的文件名。文件名的对应关系,一部分在数据库里,一部分是C#代码。
你打算怎么实现?牛同学准备写C#程序读数据库。
我建议的方案是这样的,一个标准的对付流程。
(1) 写C#程序,就是那段算法;(2) 把数据库里的作为算法输入的那一列复制到C#代码里;(3) 让段C#程序,输出很多行这样的文字:mv "源文件名" "目标文件名"
以上,用C#生成了shell程序或批处理,然后跑一遍就改了所有文件名。C#本身并不操作数据库 (人手拷过来的),也不操作文件系统 (由shell程序完成)。
如果算法变了呢?如果源文件列表变了呢?如果……所有这些问题的答案都是:重新跑一遍上面的流程。用人,而不是用程序的可重用性。
当鳄鱼冲上来咬你的时候,有一种情况,你绝对不要用刀。那就是,你手头没有刀的时候。另一种情况,不建议用刀。那就是,你用刀非常不熟练的时候。你可以抱住鳄鱼的嘴,它的咬合力惊人,但是张嘴的肌肉非常软弱。这个时候,并不是你训练自己用刀的时候。
同样的,当你不熟悉数据库操作,不熟悉在C#里文件系统操作的时候,你应该做的是 不用它们。项目是用来解决问题的,其原始动机不是给咱们训练技术的--技术可以在自己练习的时候做。项目唯一能训练的,是工程能力。就像鳄鱼问题能训练的是随机应变和灵活寻找解决问题的手段。
3. 例2
我有个top250电影目录,下载的时候不知怎么整的,文件名非常长,而且中文部分是乱码。一直准备把中文部分都删了,长期拖延,昨天晚上整了。
原始的文件名类似于:Top093.罪æ¶åŸŽå¸‚.Sin.City.UNRATED.ReCut.EXT.2005.BDRip.MiniSD-TLF.mkv
准备改为Top093.Sin.City.UNRATED.ReCut.EXT.2005.BDRip.MiniSD-TLF.mkv
这样的文件有250个。
这么整的。下面是一个整行
$ ls -1 Top* | awk -F. '{ first=$1;min=length($1)+length($2)+3;max=length($0);print ("mv \"" $0 "\" "first "." substr($0,min,max))}'> ren.sh; chmod +x ren.sh
然后,执行这个脚本,文件名就都改完了。文件中有 ' 或 ( 的,可能会出错。
ren.sh这个脚本,是重定向输出的前半段产生的。这是unix系统管理中常用的一个手段,用程序A生成一个脚本,用生成的脚本,而不是直接用程序A解决问题。
脚本的内容是很多个这样的行,下面也是一个整行:mv Top093.罪æ¶åŸŽå¸‚.Sin.City.UNRATED.ReCut.EXT.2005.BDRip.MiniSD-TLF.mkv Top093.Sin.City.UNRATED.ReCut.EXT.2005.BDRip.MiniSD-TLF.mkv
4. 例4
做等级考试的系统时,要批量ping机器以确定每台机器网络正常。我也使用了类似的方法,用C生成ping.bat。bat里面是很多ping目标地址,及只ping一次的参数,似乎还有一个超时设置为半秒的限制;C负责循环IP地址,好象是这样printf ("ping -n 1 192.168.0.%d", i++);。
IP地址的循环,我也用excel实现过。那套方案里,连C也不用。excel的几例中,有一例是文字"ping -n 1 ",其余几例是IP地址的4个部分,其中最后一部分用ctrl实现数字的递增。
更早,也更朴素的方法,我用记事本复制第一行ping,然后粘贴几次,每次复制已粘过的,行数翻倍增长;然后再手动修改IP地址最后一段。
这些方法都很朴素,但是有效。
5. 总结
核心思想是,用代码生成代码;在这个过程是,保持注意目标是"小工具",抛开重用的幻想。
关同学前两天提到,我们在既往的开发中,代码最终都没有重用。我想,代码不必重用,或者说,我们远没有达到那个高级阶段。能够解决问题,并重用解决问题的手段--设计,就非常不错了。而且,毕竟设计很值钱,而代码够便宜。
--------------------博客会手工同步到以下地址:
[http://giftdotyoung.blogspot.com]
[http://blog.csdn.net/younggift]
[http://www.renren.com/268966623/profile#pblog]
分享到:
相关推荐
通过对单元测试脚本的分析和自动翻译方法, 将原测试脚本中包含的信息提取出来, 解析为基于XML的中间脚本, 然后再利用XSLT技术, 依据XML记录的信息, 自动生成目标框架的单元测试脚本, 从而解决单元测试脚本的重用问题...
原生JS编写的滑动门效果 重用性高,精简代码 重用通用滑动门脚本原生js 兼容多平台
pb生成可重用的数据窗口;pb生成可重用的数据窗口;pb生成可重用的数据窗口;pb生成可重用的数据窗口;pb生成可重用的数据窗口;pb生成可重用的数据窗口;pb生成可重用的数据窗口;pb生成可重用的数据窗口;pb生成可重用的...
0好1警告2严重3未知只要退出代码正确,就可以用任何语言编写。 Perl是标准通常默认情况下会安装Python / Bash,并且更易于使用默认情况下通常不安装Ruby里亚克·纳吉奥斯(Riak Nagios)建造make escript部署方式...
主要内容包括如何使小到中型的系统管理任务自动化,分析系统数据并编辑配置文件,使用bash和ksh等编写IAnux、Unix和OSX应用程序的脚本文件等。 《Shell脚本专家指南》面向中高级的shell程序员,以及需要解决日常问题...
脚本:可重用的脚本
这个生成器是由 Yeoman 为 AngularJS 生成可重用 UI 组件集合的脚手架工具。 依赖关系 javascript 的包管理器: 包管理: 流式构建系统: 用法 安装 Yeoman npm install -g yo 安装generator-ngtasty : npm...
Fragment使用系列--(1)可扩展FragmentTabHost的精妙用法 demo代码。
作为一个开发期间的脚本管理工具,让开发者在开发期间享受JSI带来的种种便捷,也可以作为一个运行时的脚本管理框架,让类库编写者能够自己管理好自己编写的类库的相关依赖,让类库的最终用户从繁琐的依赖管理中解脱...
Python脚本和代码以“使用包围锥嵌入的分级图像分类”格式生成和转换图像 参考 描述这个方法能使纸张的arXiv上找到。 可以在找到实现此学习算法的存储库。 再生产 该存储库包含在不同数据集上重现论文结果所需的...
2.库的使用:Python具有强大的标准库和第三方库,可帮助自动化脚本完成各种任务,例如os库、paramiko库、requests库、selenium库等等。 3.面向对象编程:自动化脚本可以使用面向对象编程的思想,提高代码可重用性...
每次(写完最后一个之后,足以忘掉所有细节)每次我都需要编写一个shell脚本: :face_with_monocle: “我希望这是可重用的,所以我将使用适当的选项和帮助消息” :thinking_face: “嗯,是getopt还是getopts?...
单元测试框架下的软件测试将产生大量的测试脚本, 在软件测试过程中如何有效利用现有的测试脚本, 实现软件测试脚本(代码)的重用成为业界关心的一个重要问题。业界最常见的复用需求是当开发项目更换新的测试框架时, ...
实用工具个人脚本和实用程序这是什么? 这是我的Github存储库,用于未授予单个存储库的小型工具,实用程序和脚本。... 如果遇到包含,包含或使用任何或所有这些脚本的项目,则需要遵守该项目的许可证。
CloudRunner.IO代理工具和API ... 图书馆管理:存储,将脚本重用到不同类型的存储中-GitHub,ButBucket,SVN,Dropbox,Google Drive,Microsoft OneDrive等。 工作流管理-在不同的服务器上运行多步骤脚本,
1、 使用脚本文件编程的方法 2、 说明 2.1概念 脚本文件是包含一系列的命令和函数的程序文件,扩展名是.m 当需要把多个程序语句组合起来完成一项总体运算和功能时,常用脚本文件,方便存储、管理和重用,是...
循环滚动矩形v1.05 这些脚本有助于使ScrollRect Reusable ,因为它只会在需要时构建单元格。 如果滚动矩形中有大量单元,则绝对需要它! 它可以节省大量的加载和绘制调用时间,以及正在使用的内存,同时仍可以正常...
MySQLDumpX bash脚本的集合简化了MySQL数据库的部分备份。介绍随着Web应用程序变得越来越复杂,其数据库中表的数量也在增加。 除了内容和配置之外,许多当前的Web应用程序还将临时数据或聚合数据存储到数据库中。 ...
文档以易读、可重用为目标,深入浅出介绍了从MATLAB simulink 生成代码的步骤、配置等。