6

是莽撞人就来单挑:关于自动格式化 R 代码的求助

 3 years ago
source link: https://yihui.org/cn/2017/02/formatr/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

是莽撞人就来单挑:关于自动格式化 R 代码的求助

谢益辉 / 2017-02-26


2021-03-22 更新:下面的第一个愿望已经在 formatR 1.9 中实现。


2010 年我发布了一个叫 formatR 的 R 包,它可以把乱糟糟的 R 代码自动清理成大致整齐的代码(例如自动加空格、换行等),这个包也是我当年做 knitr 的小小动力之一。虽然 formatR 是个小麻雀包,但它的开发过程中也有三个里程碑事件:

  1. 最早的时候,怡轩想出了一个非常聪明的黑魔法,让这个整理过程能尽量保留代码注释;

  2. 后来 Kohske Takahashi 大人提供了一个很漂亮的黑魔法,可以让赋值的等号自动被替换为左箭头;

  3. 等啊等,终于等到 R 里面出现了 getParseData() 函数,让我终于不用红着脸用正则表达式去解析代码中的注释了,而是可以大大方方用官方 API 去解析;

然而,我对这个包还有两个小小的夙愿一直没能实现。虽不至于让我晚上睡不着觉,但若能实现,那真真是极好的。第一个愿望是,我希望能(尽量)控制代码的最大宽度。目前 formatR::tidy_source() 的宽度参数 width.cutoff 源自 deparse() 函数,而这个参数的大意是尝试在多少个字符宽度之后尝试断行,而我希望能在多少个字符宽度之前断行。因为如果之后断行,万一那个位置上恰好有个很长的变量名不能被折断,那就要等到这个变量名之后才能尝试换行,于是代码可能会超出右边界很多,这对需要 PDF 印刷品输出的写作来说是个灾难,调整起来很费神。

第二个愿望是如果小括号里的参数太多的话,就在小括号之后直接断行(原因在前面的日志中解释过),比如:

my_sum = function(
  a = 1, b = 2, c = 3, d = 4, e = 5,
  f = 6, g = 7
) {
  return(a + b + c)
}

my_sum(
  a = 1, b = 2, c = 3, d = 4, e = 5,
  f = 6, g = 7
)

目前 tidy_source() 函数只能做到:

my_sum = function(a = 1, b = 2, c = 3, d = 4, e = 5,
  f = 6, g = 7) {
  return(a + b + c)
}

my_sum(a = 1, b = 2, c = 3, d = 4, e = 5,
  f = 6, g = 7)

当然这个不算糟糕,我可以忍。这两个愿望我更迫切需要实现第一个。客官们可能会想能不能给 R 里面的 deparse() 函数打个补丁,让它既支持最大宽度也支持最小宽度,如果能打补丁并且 R 核心团队愿意接受的话,那也是极好的,但显然我没有这个技能,因为 deparse() 的源代码是基于 C 的,我一看一千多行就两眼蒙圈,但我有一定的把握去游说一位核心团队成员接受它。如果想靠自己造轮子的话,那么应该就是两条可能的路1:一是 getParseData()(注意它有坑会截断长字符串),二是用 sourcetools 包,这个我没用过,但看起来也许比 getParseData() 更容易操纵一点,而且作者是敝司的同事,有问题可以直接找他解决。

若客官们还有闲情逸致,可以顺便把这两个功能也一并实现了(#57#62)。好了,黑客骚年们,我在世上最大的同姓交友网站上等你们的合并请求。


  1. 其实还有第三条非常黑的路,就是暴力尝试不同宽度,看能否找到一个合适的,这个我当年我迫于 R CMD check 的压力早已经在 Rd2roxygen 包中试过了。所以不要跟我比黑招,我琢磨起黑招来我自己都感到害怕。除非是被逼急了,别一言不合就暴力求解。

职业羞耻感 知乎范儿

Disqus Utterances Preferences

© Yihui Xie 2005 - 2020

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK