Ruby 社区的魏玛时代:作者借新增 gem 数据反驳 DHH 看空 Rails
Living in the Weimar Era of Ruby
Ruby 开发者 julik 撰文回应 DHH 在 RailsWorld 看空 Rails 的发言,借魏玛德国历史类比提出 LLM 正在让 Ruby 社区进入复兴阶段。
原文给出 rubygems 过去一年新增包翻倍的数据与 PDF、Parquet、Qt 绑定等具体新库,可量化对比 DHH 对 Ruby 生态的悲观判断。
关于 DHH 在 RailsWorld 上发表的主题演讲,众说纷纭。对我而言,那是一个身处存在主义危机、同时又极度愤世嫉俗的人发出的声音。"看看我有多不在乎,你也应该不在乎"——当你身为自己曾四处游说才促成的(姑且称之为 CareConf)大会的头号发言人时,传达这样的信息并不合适。
这位至高领袖传达的信息十分明确:我们用 vibe 方式重写了 HEY,性能更佳,效果良好,我们不再需要 Rails,也不在乎它了。我真心认为,他与其靠充满恶意的"真相轰炸"博取更多掌声,不如干脆把他不再喜爱的玩具——连同围绕它的社区——安安静静地放下。
但问题在于:那些功成名就的人对好东西失去兴趣,并不意味着我们也必须如此。相反,它反而腾出了空间。
🧭 我目前可以承接合同工作。 雇用我 来帮您把 Rails 应用做得更好!
我必须承认,那几天我对这一切感到十分沮丧,倒不是因为"AI 写所有代码"——这一点我心里十分清楚,我也不会为这门手艺格局的变化而哀叹——真正让我叹息的是使用方式的格局,这又是另一个话题了。显而易见的是,LLM 已经扎下根来,逐行手动敲代码也不再可持续,天平已经大幅倾斜。让我感到沮丧的是,对 Ruby 生态与社区的漠不关心,以及 David 为了——正如他所言——"让它跑在一个树莓派上",而对整个 Rails 与 Ruby 文化所展现的那种轻蔑,将其一笔冲入下水道。
我实际观察到的却是另一番景象:一股复兴的浪潮,尽管不少知名的 Ruby 开发者已经转向了其他技术栈——而这些栈如今对探索更加开放,因为你不必亲手去写那些……累赘——直说吧,就是累赘。逐位拆解 7 个小端整数既谈不上有趣,也谈不上有什么艺术性——它只是累赘,我不会留恋它。除非为了让它跑得更快必须做结构体打包,但即便如此,我们总可以另行"艺术指导"。
德国历史上曾有过一段有趣的时期,恰好夹在两次世界大战之间——"战间期",即魏玛共和国时代。那是一个动荡不安的年代,许多方面一点也不光彩——社会困境、失业、惊人的通货膨胀、恶劣的居住条件、各种光怪陆离的运动、歌舞表演与异端的涌现……但也有另一面。魏玛德国的"咆哮的二十年代"还孕育出了数量惊人的伟大、奇崛、迷人的艺术运动。从包豪斯到柏林的同志歌舞秀,从库尔特·魏尔到弗里茨·朗的《大都会》——那是一个蓬勃发展的时代,许多彼时涌现的成果至今仍受珍视。
那同时也是一个技术飞速发展的时代——电力的日益普及、现代药物的大规模应用、地铁、汽车……一个令人着迷的年代。
我知道那个时代是如何收场的,不——那并不是我打这个比方想引出的部分。我真正想说的部分是:旧秩序已失去兴趣,没有人担当主角,地面在每个人脚下挪移——而恰恰在这种时刻,最有趣的作品才得以诞生。巨大的动荡、深刻的工业变革、没有任何"大人"在场监督。听起来是否有些耳熟?
Ruby 社区向来富有艺术气息,从 _why 的早期作品便可见一斑。说到底,正是美学把许多人引向了 Rails。不用加括号;单词也不会挤成一团,仿佛出自荷兰人之手;也没有『这是属性,那是方法』的困惑……这门语言在许多方面都堪称美学上的杰作。
面对如今层出不穷的新工具,审视生态现状的正确心态是这样的:
你说的没错,但这是否也显得有些短视?你拥有前所未有的最强工具,已经成为千倍效率的创造者,难道还想不出怎么把技术栈提升十倍吗?
没错,Rust 是快的,类型系统也能捕获 bug,但语言之外还有太多东西。
* 为什么不把 Ruby 提速十倍?
* 为什么不让 Ruby(进而让 Rails)在并发方面真正强大起来?
* 为什么不给 Ruby 加上比 Rust 还要强悍的类型系统?
* 为什么不把 SQLite3 嵌入 Rails,再配以复制协议,从而把整个技术栈压缩到单台服务器之外?
* 如何抢先修复 Rails 最关键部分(比如数据库连接池)的大部分 bug?是啊,谁在乎 ActiveSearch 呢,可我们能从根本改进技术栈的方式远不止让 AI 代理乱吐代码。Phoenix 仍是唯一自带 presence 的框架,因为这其实是个看似简单、实则极难做对的难题,可不知怎么所有问题都被解决了?
我理解有些人对以上任何事都毫无兴趣,这没问题,但至少请把接力棒交给那些正想这么做的人。
附:我说这一切都出于爱 ❤️
September 26, 2026
在 Ruby 如今能够做到的诸多事情里,为什么偏偏选择做 Rust 风格的改写?诚然,故事是这样讲的:我们手头那些应用都会神奇地蜕变为加速的、晦涩的、塞满 SIMD 的二进制黑箱——LLM 把我们每一个决策(无论显性还是隐性)一并翻译出来,再佐以严谨的对比测试(或者读读茶叶矩阵系数)。既然可以把这片花园铲平、换成光彩夺目的混凝土,又何必把宝贵的 token 浪费在改善我们已经身处其中的花园上?
但当然没人真的这样做
而且,幸运的是,推倒重建并不是唯一发生的事。否则这个故事就太悲伤了。
你看,Ruby 运行时和所谓的“生态”存在着大量技术上来说“太过分”的问题。
- 想要生成带排版的 PDF 简直是一种折磨——根本没有相关库
- 也无法再构建原生 GUI 应用——同样没有库
- 你也无法轻松产出原生 gem——除非你准备好精确无误地敲出成百上千个
ubf_unblock和INT2FIX……
这些都是糟糕透顶的问题。即使是三个人组成的团队都难以承担,有时就算再多一些人也不够。把这些改进引入应用的门槛很高——就算我们解决了这些问题也一样,因为在大多数公司 Rails 应用的发布周期并不快。很多人只会绝望地摊开双手,念出那句可怕的咒语:
反正也没人拿 Ruby 做这种事。
我们都记得,「恐惧咒语」的咒语剧本是这样的:就在我们念完「Rails 开发者难招」之后,所有讨厌 Ruby 的人就会跳起一支小舞,证明他们是对的。
但就在现在,这个等式已经发生了巨大变化。让我给你一个简单的例子。
生成发票可不是那么简单。
Ruby 的典型糟心事之一一直是 PDF 生成。就在 18 个月前,一个愿意从 Rails 应用里生成 PDF 文件的 Ruby 开发者还要面临一堆同样毫无吸引力的选择:
- 运行 Gotenberg,让 Chromium 渲染 HTML,再把它转成 PDF
- 使用 Ferrum 启动一个本地 Chromium,做同样的事
- 使用 Prawn,并与它那种几乎逐字符的手动坐标定位作斗争
- 使用 wkhtmltopdf——一个近四年前就已停更的项目——还得折腾它的构建及其必要依赖
Prawn 当年很出色,但非常棘手——主要是因为它要求近乎完全手动布局,没有任何合适的度量(metrics)或排版引擎(composer)特性。排版引擎就是帮你放置并平衡排版字符,使它们恰好落入预设尺寸块的机制。有时你还希望能调整那个块,让布局看起来更美观——这恰恰是 CSS 真正擅长的。你还想要断词和 SVG 输出……
虽然 Cursor 和其他「第一波」AI 工具让折腾 Prawn 舒服了一些,但在各方面距离「轻松」仍然差得很远。
这正是「在 Ruby 里做 X 很烂」的标准定义,对于某些人来说,这是一个完全正当的理由——根本不用这个平台。也别提为了运行额外的微服务(或者该叫「巨型服务」——考虑到其规模,任何内置了 Chromium 的 Docker 镜像都该叫这名字)。
好了——快进到今年九月。就在短短几个月里,我们有了不止一个,而是两个极其优秀的PDF 生成库。
Waka 打造的 sghtmltopdf 创造性地重新想象了 wkhtmltopdf——用 vibe 出来的、基于 Rust 的排版引擎替换掉它的 WebKit 内核,该引擎构建在 Servo crates 之上,支持相当一部分 CSS 布局指令——还加入了一组来自 Typst 的诱人 Rust 库,用于字体处理、度量、行排版……我大概花了一小时,就把整套发票生成从 Ferrum 迁了过去。最初它还有些毛刺,但社区大约一周就把它们打磨干净了,然后就变得很棒。不是那种「3 个文本块的手动证书布局」的棒,而是真正的「6 页带表格、块和矢量图形的发票」的棒,生成一份文档只需两位数毫秒。
Mikael Henriksson 打造的 stationery 走了另一条路——更接近 Prawn,还加入了恰到好处的 Phlex。它坦然接受一个事实:PDF 说到底只是……文本——因此,理应毫不掩饰地从任何能在某处写入文本文件的工具里输出。它适配了 Phlex 风格的视图组件与块,用一些讨喜的布局原语把它们包裹起来——结果就是一种更贴近 Ruby 精神的 PDF 输出方式,性能可与 sghtmltopdf 的 Rust 内核相媲美。
我能够在很短的时间内重新适应两者,但仍然有点难以做出选择。我们很快从“所有可用选项都非常糟糕的绝对荒原”变成了“你可以在两个很棒的选项中选择”。
我们做事是因为我们想做。
而这并不止于 PDF。Qt 绑定再次进入开发中——体面的、重量级的 Qt 绑定。自打我记事以来,这在 Ruby 中一直是个糟糕的领域。Schwad 以 Scarpe 的形式让 Shoes 重获新生——不再是那种需要 SWT、JRuby 以及一大堆东西的乏味的 Java jar,而是一个由 Ruby 脚本驱动的、拥有原生图形支持的真正图形后端。RMagick 再次定期发布,并且运行得相当漂亮。GD 绑定也正在开发中。
就我个人而言——我曾经面临过一些涉及 Rails 的较大 ETL 项目,而我总是会遇到的一个痛点就是 Parquet。在 Rails 应用中根本无法方便地输出它——我们总是不得不降级到 CSV,或者搭建一些奇怪的 CDC 流水线来完全绕过应用,只是为了产出一个数据湖。当时我的看法是,Parquet 严重过度工程化,而你用一把钝叉子就能搞定 CSV。而且在任何并非 100% 原生于 Apache 大数据文化(即不是 C++、Java 或 Python)的环境中使用它都是一种痛苦。
这让我很恼火。不,不能是这样——“我们的小玩具语言就是太慢、太小,反正谁在乎它”——Parquet 文件不过是字节而已。又一种自家发明的七拐八拐的字节编码约定、结构体重复、可插拔压缩模块和原生宽度类型,以及一些用于编码的设施……它就是复杂得过头。它并没有特殊到需要原生代码,也没有大到需要一整架子 JAR——它只是麻烦到让人不愿去处理。现有的少数库都是通过链接 GObject 以及天知道什么其他东西来处理的。这种荒漠状态持续了十多年。现在我能够在短短几天内构建出一个完整的 Parquet 库——herringbone。在 Rails ETL 中曾经令人头疼的一个问题如今完全不成问题——有一个 Ruby 库,对人和对代理都很方便,它支持流式处理,在合适的地方使用原生压缩模块,并且只需极少的用户代码——即使是对 Parquet 加密这样相当高级的功能。
不,你确实还不能真正一把梭出这样一个库。你确实需要知道你想要什么,也确实需要反复迭代,让它变得完善而快速。或者换种说法:你会一把梭出来,但结果在美学上不会好看。Ruby 的东西必须(从感觉上)看起来好看。现在我不再需要花上几天去弄清 Thrift 位打包的错综复杂(我也不怀念那破玩意儿)——我可以自顶向下设计 API,并引导 LLM 完成它。
以前,制作这样一个库需要花上我几个月的时间。制作 zip_kit 花了 3 个月(在十年间分摊完成,其中 2 个月集中在它诞生之初),而 Parquet 规范的大小是 ZIP APPNOTE 文档的 5 倍。如果说 ZIP 是一次建筑学上的迷醉之旅,Parquet 便是恐惧与厌恶式的建筑学太空冒险。
更别提我不得不匆匆凑出的约 6 个微库,仅仅是为了调用那些懒得提供 Ruby SDK 的云服务。还有至少 2 个特性开关服务的库,我知道它们的质量和/或打包都堪忧,很可能需要一些逆向和重做,做得漂亮一些。
我们做事,是因为我们需要做
Ruby 和 Rails 应用另一个典型的痛点就是 gRPC。我至今还没见过哪个 Ruby 程序员在愤怒中用过 gRPC 却没踩过任何坑的。悬挂线程、对 fork 不友好、奇怪的 protobuf 兼容性问题……问题清单可以一直列下去。现在 Samuel 直接去重做了一个对 Async 友好的 gRPC——因为我们不再受制于"X 公司的大团队在维护这个东西,而他们今年已经被重组了 6 次,没人搞得清楚是怎么回事"这样的约束。我们可以把那该死的东西直接扔进 LLM 碎木机,让它帮我们搞清楚,然后从一开始就按应该有的方式把它做出来。
作为 gRPC 基础的 Protobufs,在 Ruby 的世界里也绝非易事。它看起来非常简单,甚至可以说是平凡——把几个字节pack进一个二进制字符串到底能有多难?
结果是——你可以让它变得和你团队里允许触碰这东西的 staff/principal 工程师人头数一样难。官方的 Ruby protobuf gem 需要原生代码。每个 proto 消息都是一个原生对象的句柄,无法被 marshal 或轻易分派到另一个进程。反射能力有限且 API 怪异。你还需要一个单独的包(protoc,即 protobuf 编译器),仅仅是把一个.proto文件转换成一个包含一些样板代码(用来标注你所携带的字段)的 Ruby 文件。说实话,对于一个Marshal.dump来说,这完全是杀鸡用牛刀的庞然大物——还得拖着一大堆原生编译代码。
而原生代码需要编译。还需要为你需要支持的好几个平台 × Ruby 版本提供 ABI 兼容的预编译 gem。而推荐的 Ruby C API 在不同版本间会发生变化。它还会拖累 GC,除非你非常、非常小心,并且需要细致入微的 GVL 管理才能保证性能……
我们是不是就该忍受这些,并把它当作理所应当?这就是下一个目标。如果你也想要这个东西——联系我,我可能手头有东西可以让你玩玩。
扯淡归扯淡,统计还是要看
轶事归轶事,但我想验证一下我所看到的这些是否只是我自己时间线里的一个泡沫。所以我去ClickHouse 托管的 rubygems 数据集那里,统计了一些相当愚蠢的东西:过去十二个月里,有多少 gem 的名字是第一次被占用的,对比之前的十二个月。不是下载量,不是版本数——只是"一个在 rubygems.org 上不存在、但现在存在的名字"。
那个原始数字毫无意义——它包含了几千个被下架的 typosquat,还有零星几个账号每个 API 端点就发一个 gem——所以所有未被索引的全被剔除,所有来自三个或更少账号、20+ gem 的前缀家族也都被剔除。剩下的就是那些无聊的、原生的、一次性的东西——sidekiq-buffered、schema_reaper、k8s-rails、rspec-hopper。其中截至 2025 年 10 月的那一年大约有 4600 个,而之后的这一年大约有 8900 个:是原来的 1.9 倍。这条曲线在整个 2025 年都维持在每月大约 400 到 500 个,然后从 2026 年 3 月开始跳到了每月 800 到 1600 个。这不是一条斜坡,这是一个台阶。
这就是大家一直在谈论的软件繁荣,它也降临到了我们这门小众语言上。我无法告诉你这些人是新面孔,还是同一批人正处于高产期——数据不知道,我也不知道——但人们所需要的那些东西,被打包发布出来的频率是过去的两倍,而不是被「恐惧咒语」一耸肩打发掉。质量如何随你评判——有些是垃圾,有些是herringbone,由你来判断哪个是哪个——但「把这东西做出来」这个决定,被做出的频率是一年前的两倍。这就是我所说的复兴。
无需借口
而这不仅仅是库的问题。性能是一个非常值得攻坚的话题。Sam Ruby 正在做的他的 Roundhouse 交叉编译器工作非常出色,能让我们通过一些没人想到过的野蛮粗暴的优化,跑出更快的应用程序。Tobi 出手用纯 Ruby 而不是 Rails 重写 Campfire——Falcon、Ractors、SQLite 上的普通模块、字节一致的 HTML——结果页面响应速度提升了 15 到 27 倍……
而这一切让所有使用 Ruby 和 Rails 的人生活都变得更好,就在今天。不是「等一年后大模型迎头赶上」,也不是「等你的 CISO 终于批准 GitHub Copilot」。更不是「等几个月后我们把治理策略理清楚再说」。就是今天。
我们真的可以着手去修复那些多年来一直令人头疼的东西,快速搞定,也花不了多少钱。
我们唯一需要的就是保持适度的好奇心,而不是坐等许可。1925 年的柏林,没有人等着皇帝回来批准卡巴莱演出——皇帝已经退位去了荷兰,而卡巴莱反而因此变得更加精彩。
我们有工作要做。他没有:
先生,我已经很有钱了。我最不想要的就是更多的客户 😂
August 19, 2026
来源:Hacker News · blog.julik.nl