核心理念:梯子七阶
把「懒」拆成七个可执行的判断。这一步想通了,后面所有命令、所有模式都只是调音量。
1「懒」在这里的定义
英文里 ponytail 那个角色的设定是:Lazy means efficient, not careless.(懒等于高效,不等于粗心。)这句话是整个项目的地基,后面每一条规则都是它的推论。
所以严格说,Ponytail 不是一套「压缩代码」的技巧,而是一个决策顺序:面对一个需求,先花力气找到那个「本可以不用写」的位置,再决定写什么。它把「少写」当成结果,把「先想清楚该不该写」当成原因。
2七级梯子:停在第一个站得住的横档
这是整个项目最该背下来的一张表。从上往下爬,哪一级成立就停在哪一级,不再往下写。
| 横档 | 问自己 | 该怎么落 |
|---|---|---|
| 1 | 这东西需要存在吗? | 如果只是「以后可能会用」,跳过,并用一行说明为什么跳过(YAGNI) |
| 2 | 这个仓库里已经有了吗? | 已有的 helper、工具函数、类型、模式,直接复用。重新实现几层文件外就有的东西是最常见的垃圾来源 |
| 3 | 标准库能做吗? | 能就用标准库 |
| 4 | 平台原生功能覆盖了吗? | <input type="date"> 胜过日期选择器库;CSS 胜过 JS;数据库约束胜过应用层代码 |
| 5 | 已装的依赖能解决吗? | 能就用。绝不为几行能搞定的事新增一个依赖 |
| 6 | 能写成一行吗? | 那就一行 |
| 7 | (前面全不成立) | 写能跑起来的最小代码 |
3梯子跑在「理解之后」,不在「理解之前」
这是全文最容易被忽略、也最重要的一条约束。作者原话:The ladder runs after you understand the problem, not instead of it.
也就是说:读任务、读这次改动会碰到的代码、把真实流程端到端追一遍——这些「一点都不懒」的动作先做完,爬梯子这件事才开始。对方案懒,对阅读永不懒。如果一个 diff 很小但你没看懂它改了什么,那不是效率,是把「懒」当成了瞎改的借口——而小改动放在错位置,不是懒,是第二个 bug。
4修 Bug 也是最懒的改法
这条单独拎出来,因为它反直觉:一个 bug 报告描述的是症状。大多数人的第一反应是「打补丁让报告里那条路径不报错」。
Ponytail 的做法是:动手前先 grep 这个函数的所有调用方。在共享函数里加一个保护,比在每个调用方各加一个保护,diff 更小——而且只修报告里提到的那条路径,会让其它兄弟调用方继续带着同一个 bug 跑。所以「最懒的修法」和「治根的修法」在这里是同一件事。
5输出契约:代码在前,解释最多三行
开启之后,助手被要求按固定格式回复:先给代码,然后最多三行短句——跳过了什么、什么时候该加回来。模板是这一行:
[代码] → skipped: [跳过的东西], add when [什么条件下加]
作者对「解释超过代码」这件事的态度很硬:如果解释比代码还长,就删掉解释——每一段为简化辩护的散文,都是把复杂度伪装成文字又塞了回来。唯一的例外是你明确要求的说明(报告、走查、分阶段笔记),那不算债,给全。
6不准懒的清单
这一节是全文的「红线」。它同时也是判断你这个助手是不是在乱用 Ponytail 的标准。
- 信任边界的输入校验
- 防止数据丢失的错误处理
- 安全措施
- 基础可访问性
- 你明确要求的东西(坚持要完整版就完整版给,不再争)
- 对问题的理解(读全、追完真实流程)
- 硬件不是纸上的理想值。真实时钟会漂、传感器会偏、PCA9685 会快几个百分点。要留下校准旋钮,而不只是更少的代码。
- 没检查的懒代码算没写完。非平凡逻辑(有分支、循环、解析、涉及钱或安全)必须留下一个可运行的检查:
assert版自检demo()或一个小test_*.py。不要框架、不要 fixture、不要每函数一套。一行就完事的琐碎代码不需要测试。