来自 赵鹏 | October 18, 2018
春有百花秋有月,夏有凉风冬有雪 。
若无闲事挂心头,便是人间好时节。
上回提了一句,说被自己开发的 bookdownplus 包给坑了。受它和其他几个 R 包所累,这一年来,我总想关起门窗,静静清除包包里的几只 bugs,不清掉的话实在睡不香。于是乎,把阿尔卑斯山的春花秋月全都错过了。
简单来说,被坑的原因只有一个:没有金刚钻,硬揽瓷器活。
bookdownplus 诞生之前,《学 R:零基础学习 R 语言》一书刚刚完稿,我正处于摸索 bookdown 的兴奋期。当时遇见了三件事:第一是 RStudio IDE 还不具备直接创建 bookdown 项目的功能(比如说每次都要从源头拷贝一份 .Rproj 文件),第二是我头一回接触 yaml(每次都要翻书),第三是我电脑里有一堆尘封已久的 LaTeX 模板,食之无肉,弃之有味。
这三件事,任何一件孤立起来,都直接翻篇儿,然而叠加起来,产生了协同效应。我先是把常用的文件整理成了一个 Github 项目,并且写了个 R 脚本,灭掉了这三个问题。后来心念一动:写都写了,不如把这个脚本写成个 R 包,发到 CRAN 上分享!
一失足成千古恨。现在回头去看,这是未来一年里一切灾难的开始。
R 脚本,自用是一回事,而分享,完全是另一回事。哪怕这只是最简单不过的一个包。
第一个坑很快来了,那就是包的命名:这个包叫什么好?
这个坑说大不大,说小不小。说它不大,是因为不重要,不论起多好的名字,烂包不会变好包;说它不小,是因为为它花的时间比预计得要多。
原想叫 bd,意思是 bookdown 的简化,但猛一看让人摸不着头脑;
后来想叫 bookup,梦想着跟 bookdown 出双入对,但细想却好像是跟 bookdown 对着干;
最后,选择了 bookdownplus,长是长了点,但好处是在 CRAN 的包列表里紧随 bookdown,亦步亦趋;并且,用 library()
加载 bookdown 时,如果按 tab 自动补全的话,会有 bookdownplus 的提示。我还为 bookdownplus 做了个 logo,由三个元素构成:book,down,plus。
瞧我是有多闲。
第二个坑,是发布到 CRAN。没想到有那么多讲究。
一个包,在本地电脑里运行得好好的,然而想发布到 CRAN,就得先自检。当然,这个得感谢 RStudio,让人只需点个按钮,就能模拟提交到 CRAN 会遇到的警告,然而这只是降低了入门的门槛;迈进门槛之后,该受的虐一个也少不了。
依赖的包没导入,不行;导入的包没使用,也不行;函数没举例子,不行;函数举了例子万一出错,也不行;甚至函数的标题里,单词首字母的大小写写错都不行。有时候,光提交就能耗进去半天。自检出来的 Warnings,Errors 以及 Notes,哪怕解决之后,CRAN 管理员仍然会在回复邮件指出各种错误,这足够一个业余程序员怀疑人生了。
后来,我做出一个决定:升级到 github 就够了。至于提交到 CRAN,还是算了吧,除非万不得已。
第三个坑,是兼容性。
我是个 Windows 用户;这个包只在 Windows 下测试过。更准确地说,只在 Windows 7 下测试过。发布之后就得到反馈,说某个模板在 Mac 或 Linux 下出现这样那样的故障。作为开发者,自然而然地想到去同样的环境下测试,那么问题就来了:装个 Linux?虚拟的 Ubuntu 我是装过,但只是玩玩而已,现在要测试,就得升级 R——光升级 R 就用尽了我的洪荒之力。这还是好的,更糟的是 Mac 环境,我怎么去虚拟?
嘿,还别说,我还真的下载了个黑苹果系统,结果装上一试啊,电脑死慢,动一下鼠标,等 5 秒钟,显示器上的鼠标箭头终于颤抖了一下,告诉我它其实没死,只是活得有点累而已。
如此这般折腾一圈,我才想起来自己最初想要做什么——不就是把几行代码分享出去吗,至于这么麻烦?
第四个坑,是升级。不是 bookdownplus 本身升级,而是依赖的工具链升级。
bookdownplus 依赖的工具链很长,其中任何一个环节发生变化,都有可能导致 bookdownplus 挂掉。
有一次,用户反映,由于 pandoc 的升级,原先的pandoc_args: --chapters
,要改成 pandoc_args: --top-level-division=chapter
,不然就会出现警告。
对我这种得过且过的人来说,警告就警告呗,我装作没看见,不影响结果就行。但是,bookdownplus 的用户显然要求更高一些,多人多次提出这个问题。
要说改起来也容易,不就是拷贝粘贴一下嘛。然而,bookdownplus 本质上是个模板库,我得把所有的几十个模板都改一轮。这时我就开始质疑包的开发者了:这是架构得有多差,明明只是一个问题,却要改多处?这包是谁开发的?
哦,这才想起来,这包是我开发的。
有一段时间,我用 bookdownplus 的一个模板干正经事,干了一半,放下做别的,一放好多天。期间,我大概是升级了 R,RStudio,MikTeX 里的某些包,可能还包括 pandoc,bookdown,rmarkdown,knitr……说不清楚。然后回来接着干正经事,莫名其妙地发现,编译失败。找原因?要命的是,上面任何一处都有可能是原因。更要命的是,这些我全不熟。
好吧,我就坐等 bookdownplus 的用户来提意见。
就这样被坑了多次,坑得反复怀疑人生:bookdownplus 这个包有意义吗?我适合做开发吗?分享这个包,到底是为了所谓贡献,还是出于虚荣?就像《学 R》一书“函数”一章里写到的:
以铜为鉴,可正衣冠;
以古为鉴,可知兴替;
以人为鉴,可明得失:
以 R 包为鉴,可知本我,自我,超我。
bookdownplus 的本质有两个:(1) 它是个创建 bookdown 项目的便捷方式,(2)它是个模板库。它的核心代码不过区区几十行。当初凭一时热情创建,而后来的一年里,尤其是写进《学 R》一书之后,我不断怀疑它存在的意义。
RStudio 目前已经可以直接创建 bookdown 项目,所以第一点意义已经不大。而作为模板库,我没有精力去维护几十个 LaTeX 模板。
最近, RStudio 官方举办了 bookdown 大奖赛。我觉得,是时候做个了断了。
借大奖赛的机会,我完善和添加了北京大学和中国科学院大学的学位论文模板, 算是了了一桩心愿。同时,对 bookdownplus 做出了一次最大的升级,那就是把 bookdownplus 改成了链接到 bookdown 模板的桥梁。除了自带几个模板外,我把其他模板都移了出去。并且,任何人都可以往 bookdownplus 提交自己创建或自己发现的 bookdown 模板,只需向模板展示网站 bookdownplus gallery 提交一篇介绍文字即可。接受之后,就可以直接用 bookdownplus 来下载安装了。
谁的模板谁维护,bookdownplus 只是引荐一下。
我打算从此去享受我的夏风冬雪。