Ruby on Rails 现象级的崛起很大程度上归功于新颖的技术和时机。但技术优势会随着时间而消退,良好的时机也无法单独支撑一个运动长久发展。因此,需要更广泛的解释来说明 Rails 如何不仅保持了相关性,还不断增长其影响力和社区。我认为,持久的推动者一直是并将继续是其备受争议的准则。
这个准则在过去十年中不断演变,但其最坚实的支柱也都是创始时的理念。我并不声称这些想法具有根本的原创性。Rails 最主要的成就,是围绕着关于编程和程序员本质的一系列看似异端但强大的思想,团结并培养了一个紧密的社群。
废话不多说,以下是我认为最重要的九个 Rails 准则的支柱。
没有 Ruby 就不会有 Rails,所以第一个准则直接源自创建 Ruby 的核心动机,这是非常合适的。
Ruby 最初的“异端”之处,确实是将程序员的幸福感放在首位。这超越了在此之前驱动编程语言和生态系统的许多其他竞争性但有效的考量。
Python 可能会吹嘘“做某事只有一种,最好是唯一一种方式”,而 Ruby 则热衷于表达力和细微差别。Java 极力保护程序员免受自身的影响,而 Ruby 则在欢迎工具包中包含了锋利的刀。Smalltalk 强调消息传递的纯粹性,而 Ruby 则以近乎贪婪的胃口积累了关键词和构造。
Ruby 之所以与众不同,是因为它重视不同的东西。其中大部分是为了满足这种对程序员幸福感的渴望。这种追求不仅使其与其他大多数编程环境格格不入,也与主流观念中程序员的形象以及他们应该如何行事相悖。
Ruby 不仅认识到,而且适应和提升了程序员的情感。无论是他们的自卑感、奇思妙想,还是喜悦。Matz 跳过了惊人的复杂性来实现技术上的飞跃,让机器似乎在对人类的合作者微笑并奉承。Ruby 充满了视觉错觉,那些在我们心目中看似简单、清晰、优美的,实际上是幕后复杂的线路纠缠。这些选择并非没有代价(问问 JRuby 团队尝试反向工程这个神奇的音乐盒!),这正是它们如此值得称赞的原因。
正是这种对编程和程序员的另一种愿景的承诺,将我与 Ruby 的恋情牢牢锁定。这不仅仅是易用性,不仅仅是代码块的美学,不是任何单一的技术成就。它是一种愿景。一种反主流文化。一个为现有专业编程模式下的“不合群者”提供归属感和志同道合者交流的地方。
我过去曾将发现 Ruby 描述为找到了一副与我的大脑完美契合的神奇手套。比我曾想象过的任何手套都要贴合。但这甚至不止于此。这是我个人从“因为我需要程序而编程”转变为“因为我爱上了编程作为一种智力练习和表达方式而编程”的标志性事件。这是找到了一个心流的源泉,并且能够随意开启它。对于任何熟悉 Csikszentmihalyi 的工作的人来说,其影响是难以言喻的。
我毫不夸张地说,Ruby 改变了我,并为我一生的工作设定了方向。这种启示如此深刻。它赋予了我一种使命感,去传播 Matz 的创造,去帮助传播这一深刻的创造及其益处。
现在,我能想象你们大多数人难以置信地摇头。我不怪你们。如果有人在我还在“编程只是一个工具”的范式下生活时,向我描述上面的经历,我也会摇头。然后我可能会嘲笑过度使用的宗教语言。但为了真实地叙述,也必须诚实,即使这会让人反感,甚至让大多数人反感。
言归正传,这对 Rails 意味着什么?这个原则又是如何继续指导其发展的?为了回答这个问题,我认为回顾一下早期用来描述 Ruby 的另一个原则会很有启发:最小惊喜原则。Ruby 应该按照你的预期行事。这与 Python 形成鲜明对比。
$ irb
irb(main):001:0> exit
$ irb
irb(main):001:0> quit
$ python
>>> exit
Use exit() or Ctrl-D (i.e. EOF) to exitRuby 同时接受 exit 和 quit 来满足程序员退出其交互式控制台的明显愿望。而 Python 则固执地指示程序员如何正确地完成请求,即使它显然知道你的意思(因为它显示了错误消息)。这是一个很明确的,尽管是小小的,PoLS 的例子。
PoLS 在 Ruby 社区中失宠的原因是,这个原则本质上是主观的。对谁来说是最小的惊喜?当然,对 Matz。以及那些以与他相同的方式感到惊讶的人。随着 Ruby 社区的壮大,那些以与 Matz 不同方式感到惊讶的人的比例也随之增长,这成为了邮件列表中无休止的无谓争论的根源。因此,这个原则逐渐淡出公众视野,以免引发更多关于 X 人对 Y 行为感到惊讶与否的无结果的辩论。
那么,这又与 Rails 有什么关系呢?嗯,Rails 的设计原则与最小惊喜原则(对 Matz 而言)类似。它是一个“更大的微笑原则”(DHH 的),正如其名称所示:API 设计时极其关注什么会让我笑得更开心,以及更广泛的关注。当我这样写出来时,听起来几乎是可笑的自恋,甚至我自己也难以反驳第一印象。
但创造像 Ruby 或 Rails 这样的东西,至少在最初是一个深度自恋的活动。这两个项目都源自单一创造者的头脑。但也许我在将我自己的动机投射到 Matz 身上,所以让我把我的声明范围缩小到我所知道的:我创造了 Rails 来为我服务。首先是为了让我开心。它的效用在很大程度上服从于它使我更享受生活的能力。来丰富我日常处理网络信息系统需求和请求的辛劳。
就像 Matz 一样,我有时会采取一些荒谬的措施来服务我的原则。一个例子是 Inflector,一个类,它对英语语言的模式和不规则性有足够的理解,可以将 Person 类映射到 people 表,Analysis 映射到 Analyses,而 Comment 映射到 Comments。这种行为现在被认为是 Rails 中一个不容置疑的元素,但在早期我们仍在巩固准则及其重要性时,这场争议的火焰曾被激烈地燃烧。
另一个需要较少实现工作量,但引起几乎同样多不安的例子:Array#second 到 #fifth(以及为了好玩而加入的 #forty_two)。这些别名访问器深深地冒犯了一个非常直言不讳的群体,他们谴责(近乎文明的终结)本可以写成 Array#[1]、Array#[2](以及 Array[41])的东西造成的臃肿。
但这两个决定直到今天仍然让我微笑。我喜欢在测试用例或控制台中写 people.third。不,这不合逻辑。它不高效。它甚至可能是病态的。但它仍然让我微笑,从而实现了这个原则,丰富了我的生活,帮助我继续参与 Rails 的工作,即使已经有了 12 年的服务。
不像优化性能,优化幸福感很难衡量。这使得它几乎是一个本质上不科学的尝试,这使得一些人认为它不那么重要,如果不是完全令人沮丧的话。程序员被教导要争论并征服可衡量的事物。那些有明确结论,并且 A 可以被明确证明优于 B 的事物。
但是,虽然在微观层面追求幸福感很难衡量,但在宏观层面却容易观察。Ruby on Rails 社区中有许多人正是因为这种追求而来到这里。他们夸耀着更好、更充实的工作生活。正是这种情感的集合,使得胜利清晰可见。
因此,我们得出结论:优化幸福感可能是 Ruby on Rails 最具形成性的关键。它将继续是如此。
Rails 最早的生产力格言之一是:“你不是一个美丽而独特的雪花”。它认为,通过放弃虚荣的个性,你可以跳过平凡决策的辛劳,并在真正重要的地方取得更快进展。
谁在乎你的数据库主键由什么格式描述?它真的是“id”、“postId”、“posts_id”还是“pid”很重要吗?这是一个值得反复思考的决定吗?不。
Rails 的使命之一就是挥舞砍刀,砍掉开发者在创建 Web 信息系统时面临的层出不穷的重复性决策。有成千上万这样的决定只需要一次性做出,如果别人能为你做到,那就更好了。
配置转移到约定不仅使我们免于深思熟虑,还为我们提供了生长更深层次抽象的肥沃土壤。如果我们能依赖 Person 类映射到 people 表,我们就可以使用相同的变形将声明为 has_many :people 的关联指向寻找 Person 类。良好约定的力量在于它们能在广泛的范围内产生回报。
但是,除了为专家带来生产力提升之外,约定还能降低初学者的入门门槛。Rails 中有如此多的约定,以至于初学者甚至不需要知道它们的存在,就可以在不知情的情况下从中受益。有可能在不知道一切为什么是这样的时候创建出很棒的应用程序。
如果你的框架仅仅是一本厚厚的教科书,而你的新应用程序是一张白纸,那么这是不可能的。即使是弄清楚从哪里开始、如何开始,都需要巨大的努力。开始工作的战斗的一半在于找到一个可以着手的线索。
即使你理解所有部分是如何协同工作的,情况也是如此。当每一个改变都有一个明显的下一步时,我们可以快速地浏览一个应用程序的许多部分,这些部分与其他先前应用程序的相同或非常相似。一处放一物,万物归其位。约束能解放最聪明的头脑。
然而,像任何事物一样,约定的力量并非没有危险。当 Rails 使如此多的事情变得如此简单时,很容易认为应用程序的每个方面都可以由预制的模板形成。但大多数值得构建的应用程序都有一些独特的方面。它可能只占 5% 或 1%,但它就在那里。
困难的部分在于知道何时偏离约定。何时偏离的细节足够严重,值得一次旅行?我认为大多数想要成为美丽而独特的雪花的冲动都是考虑不周的,而且偏离 Rails 的成本被低估了,但又足够多,以至于你需要仔细检查所有这些冲动。
当你不知道什么好吃时,如何在餐馆点菜?好吧,如果你让厨师选择,你大概可以认为会有一顿美餐,即使你不知道“好”是什么。这就是 omakase。一种无需成为美食专家或拥有在黑暗中随意挑选的运气就能吃得好的方式。
对于编程来说,这种做法的好处——让别人组装你的技术栈——与我们从约定优于配置中获得的益处类似,但处于更高的层面。CoC 关注的是我们如何最好地使用单个框架,而 omakase 则关心**选择**哪个框架,以及它们如何协同工作。
这与受人尊敬的编程传统相悖,即把可用的工具呈现为独立的选项,并将选择的特权(和负担!)赋予个人程序员。
你肯定听过,并且可能点头赞同“为工作选择最好的工具”。这听起来如此基本,以至于不容辩驳,但能够挑选出“最好的工具”取决于一个能自信地确定“最佳”的基础。
这是一个类似于餐馆食客的问题。就像在八道菜的套餐中选择每一道菜一样,选择每一个独立的库或框架都不是孤立完成的任务。在这两种情况下,目标都是考虑整个晚上或整个系统。
所以,在 Rails 中,我们决定用一个更大的好处来减少一个好处:程序员选择他们工具箱中每个工具的个人特权。其红利是无穷无尽的。
因为即使是最有学问和技能的程序员来到并留在 Rails,也不太可能反对菜单上的所有事项。(如果他们反对,他们可能就不会坚持使用 Rails。)因此,他们会认真地选择他们的替换项,然后继续与其他人一起享受精心策划的、共享的技术栈的其余部分。
有一种强烈的情感吸引力是选择一个中心思想,并将其遵循到逻辑结论,作为你的架构基础。这种纪律有一种纯粹性,所以很明显为什么程序员会自然地被这种明亮的光芒所吸引。
Rails 不是那样的。它不是一块完美切割的布。它是一块拼布。是许多不同思想甚至范式的组合。许多通常会发生冲突的思想,如果单独一对一地进行对比。但那不是我们试图做的。这不是一个关于卓越思想的单一辩护,其中必须宣称一个唯一的赢家。
以我们用 Rails MVC 甜点制作视图的模板为例。默认情况下,允许我们从这些模板中提取代码的所有辅助函数只是一个巨大的函数集!甚至是一个单一的命名空间。哦,多么令人震惊和恐惧,这就像 PHP 汤!
但我认为,当 PHP 提供很少需要交互的单个函数时,它是有道理的,就像视图模板中的许多抽象一样。而且,对于这个目的,单一命名空间,大量的方法集,不仅是一个合理的选择,而且是一个伟大的选择。
这并不意味着我们不偶尔想要在构建视图时使用更面向对象的方法。Presenters 的概念,我们将许多相互依赖的方法和下面的数据包装在一起,偶尔可以是处理因依赖而变味的方法汤的完美解药。但通常证明是罕见的而不是常见的选择。
相比之下,我们通常将 MVC 分层蛋糕中的模型视为面向对象优点的主要堡垒。为对象找到正确的名称,提高一致性,并降低耦合性是领域建模的乐趣。它是一个与视图截然不同的层,所以我们采取了不同的方法。
但即使在这里,我们也不遵循单一范式教条。Rails 的 Concerns,Ruby mixins 的专业化,通常用于给单个模型提供一个非常广泛的接口。这与 Active Record 模式非常契合,因为它可以让 Concerns 方法直接访问它们交互的数据和存储。
即使是 Active Record 框架的基础本身也冒犯了一些纯粹主义者。我们将与数据库接口所需的逻辑直接与业务领域和逻辑混合。如此模糊的边界!是的,因为事实证明,这是一种实用的方法来解决一个几乎总是需要与数据库交互的 Web 应用猫的问题,以持久化领域模型的状态。
如此的意识形态灵活性使得 Rails 能够解决如此广泛的问题。大多数单个范式在特定问题领域内都做得很好,但当应用于其舒适范围之外时,就会变得尴尬或僵化。通过应用许多重叠的范式,我们覆盖了侧翼并保护了后方。最终的框架比任何单个范式允许的都要强大和有能力得多。
现在,这种与多种编程范式“多边恋”关系的代价是概念上的开销。仅仅知道面向对象编程不足以在 Rails 中获得良好的体验。最好也能熟悉过程式和函数式编程。
这同样适用于 Rails 的许多子语言。我们并不试图让你完全回避学习,例如,用于视图的 JavaScript 或用于偶尔复杂查询的 SQL。至少在达到可能性的顶峰时是这样。
减轻学习负担的方法是简单地使其易于上手,在你理解框架的每一个方面之前就能创建出有价值的东西。我们因此而快速推出“Hello World”。你的桌子已经准备好了,开胃菜也已奉上。
我们的想法是,通过早期提供有价值的东西,我们将鼓励 Rails 的实践者快速提升。将他们的学习旅程视为一种乐趣,而不是障碍。
我们编写代码,不仅是为了让计算机或其他程序员理解,更是为了沐浴在美的温暖光芒中。美观的代码本身就是一种价值,应该充满活力地去追求。这并不意味着优美的代码总是能胜过其他考虑,但它应该在优先事项的整个过程中占有一席之地。
那么,什么才是优美的代码呢?在 Ruby 中,它通常介于原生的 Ruby 习惯用法和自定义领域特定语言的力量之间。这是一条模糊的界限,但很值得去尝试和驾驭。
这里有一个来自 Active Record 的简单例子
class Project < ApplicationRecord
belongs_to :account
has_many :participants, class_name: 'Person'
validates_presence_of :name
end这看起来像 DSL,但它实际上只是一个类定义,有三个类方法调用,它们接受符号和选项。没什么花哨的。但它确实很漂亮。它确实很简单。它从那些少的声明中提供了巨大的力量和灵活性。
一部分美来自于这些调用遵循了之前的原则,例如约定优于配置。当我们调用 belongs_to :account 时,我们假设外键名为 account_id,并且它存在于 projects 表中。当我们必须将 Person 的 class_name 指定为 participants 关联的角色时,我们只需要那个类名定义。从它,我们将再次推导出外键和其他配置点。
这里是数据库迁移系统的一个例子
class CreateAccounts < ActiveRecord::Migration
def change
create_table :accounts do |t|
t.integer :queenbee_id
t.timestamps
end
end
end这是框架力量的精髓。程序员根据特定约定声明一个类,例如实现了 #change 的 ActiveRecord::Migration 子类,框架就可以处理围绕它的一切,并知道这是要调用的方法。
这使得程序员需要编写的代码非常少。在迁移的情况下,这不仅允许调用 rails db:migrate 来升级数据库以添加这个新表,它还允许以相反的方式通过另一个调用来删除这个表。这与程序员自己完成这一切,并从他们调用的库中缝合工作流非常不同。
然而,有时优美的代码更加微妙。它与其说是让某事尽可能短或强大,不如说是让声明的节奏流畅。
这两个语句做的事情相同
if people.include? person
...
if person.in? people但它们的流程和焦点却微妙地不同。在第一个语句中,重点是集合。那是我们的主题。在第二个语句中,主题显然是人。这两个语句的长度差别不大,但我会认为第二个语句更漂亮,并且在涉及关于人的条件的地方使用它时,更有可能让我微笑。
Ruby 在其功能库中包含了很多锋利的刀。并非偶然,而是有意为之。最著名的是 monkey patching:改变现有类和方法的强大能力。
这种能力经常被讥笑为对于凡人程序员来说太过强大,无法处理。来自更严格环境的人们曾经想象过各种灾难,这些灾难会因为语言赋予其使用者如此巨大的信任而毁掉 Ruby。
如果你可以改变任何东西,有什么能阻止你覆盖 String#capitalize,使得“something bold”.capitalize 返回“Something Bold”而不是“Something bold”?这可能在你的本地应用程序中有效,但随后会破坏依赖原始实现的各种辅助代码。
答案是没有。Ruby 在编程上没有什么能阻止你使用它的锋利刀刃来切断理智。我们通过约定、暗示和教育来强制执行这些常识。而不是禁止厨房里的锋利刀刃,并坚持让每个人都使用勺子来切番茄。
因为 monkey patching 的反面是像 2.days.ago(返回当前日期之前的两天)这样的壮举。现在你可能认为这是一个糟糕的交易。你宁愿失去 2.days.ago,也不愿阻止程序员覆盖 String#capitalize。如果你是这个立场,那么 Ruby 可能不适合你。
然而,即使是那些为了安全而放弃这种自由的人,也很难争辩说改变核心类和方法的强大能力已经毁掉了 Ruby 语言。恰恰相反,这门语言之所以蓬勃发展,正是因为它对程序员的角色提出了一个不同且激进的视角:他们可以被信任拥有锋利的刀刃。
而且不仅是信任,而且是教导他们如何使用这些强大的工具。我们可以通过假设大多数程序员都想成为更好的程序员,能够挥舞锋利的刀刃而不伤到自己来提升整个职业。这是一个令人难以置信的雄心勃勃的想法,并且与许多程序员关于其他程序员的直觉背道而驰。
因为当锋利刀刃的价值受到争议时,总是关于其他程序员。我还没有听过一个程序员举手说“我无法信任自己拥有这种力量,请把它拿走!”。总是有人说“我认为其他程序员会滥用它”。这种家长式的论调从来没有吸引过我。
这就引出了 Rails。框架提供的刀刃并不像语言提供的那么锋利,但有些仍然足够锋利。我们不为提供这些工具作为工具包的一部分而道歉。事实上,我们应该庆祝我们对 fellow programmers 的抱负有足够的信心,敢于信任他们。
Rails 中有很多功能曾被争议为“自由度过高”。但一个目前很流行的例子是concerns 功能。这是一个薄薄的语法糖层,围绕着 Ruby 内置的模块功能,旨在允许单个类封装多个相关但独立理解的 concern(因此得名)。
他们的指责是,concerns 为容易臃肿对象的程序员提供了一整套新的抽屉来塞他们的杂物。这是真的。Concerns 确实可以这样使用。
但主要的谬误在于认为,通过**不**提供像 concerns 这样的功能(即使是中等能力的程序员使用它也可以实现概念的优雅分离),我们会让程序员走上架构上的幸福之路。如果你不值得被信任,无法将厨房水槽从你过度填充的 concerns 中移除,那么你很可能也不会得到其他闪耀的优雅典范。
还没有学会挥舞锋利刀刃的程序员还做不出蛋白酥。这里的关键词是:还。我相信每个程序员都有一个成为完全合格的 Ruby 和 Rails 程序员的途径,甚至是一种权利。合格的意思是,足够了解何时以及如何在他们自己的上下文中,使用抽屉中不同且有时危险的工具。
这并不意味着我们不需要承担责任来帮助他们实现这一点。语言和框架应该是耐心的导师,愿意帮助和指导任何人成为专家。同时认识到唯一可靠的途径是通过犯错之地:工具使用不当,一点血汗,甚至可能还有眼泪。根本没有其他办法。
Ruby on Rails 是一个为厨师和想成为厨师的人提供的环境。你可能从洗碗开始,但你可以一直做到掌管厨房。在那个旅程中,不要让任何人告诉你,你不能被信任使用行业中最好的工具。
Rails 可以在多种环境中运行,但它的初衷是创造集成系统:雄伟的巨石!一个解决整个问题的完整系统。这意味着 Rails 关心从前端 JavaScript(用于实现实时更新)到生产环境中数据库如何从一个版本迁移到另一个版本的所有内容。
正如我们所讨论的,这是一个非常广泛的范围,但并不比一个人可以理解的范围更广泛。Rails 特别寻求赋能通用型个人来构建这些完整的系统。它的目的不是将专家隔离到小的利基市场,然后要求大量这样的专家才能构建任何有持久价值的东西。
正是这种赋能个体的关注点指向了集成系统。在集成系统中,我们可以消除许多不必要的抽象,减少层之间的重复(例如服务器端和客户端的模板),最重要的是,避免在我们绝对、肯定必须之前就分发我们的系统。
系统开发中的许多复杂性来自于引入元素之间新的边界,这些边界限制了你如何进行 A 和 B 之间的调用。对象之间的方法调用比微服务之间的远程过程调用要简单得多。那些冒险进入分布式领域的人将会面临一个全新的痛苦世界,包括故障状态、延迟问题和依赖更新计划。
有时这种分布式是必要的。如果你想创建一个 API 来供其他人通过 HTTP 调用你的 Web 应用程序,那么你就必须接受并处理其中许多问题(尽管处理入站请求而不是出站请求要容易得多——你的停机时间是别人的故障状态!)。但那至少是对你个人开发体验造成的有限损害。
更糟糕的是,当系统过早地被分解成服务,甚至更糟的是微服务时。这种驱动力常常源于一个误解,即如果你想构建一个现代互联网应用程序,你就必须多次构建系统:一次在服务器端,一次在 JavaScript MVC 客户端,一次用于每个原生移动应用程序,等等。这不是自然规律,不必如此。
完全有可能在多个应用程序和访问点之间共享应用程序的大部分内容。将相同的控制器和视图用于桌面 Web 和嵌入到原生移动应用程序中。尽可能地集中在那个辉煌的、雄伟的巨石中:集成系统。
所有这些都无需在速度、用户体验或其他吸引开发者过早分发的属性上付出太多,甚至毫无牺牲。
这就是我们所追求的“拥有一切”:拥有单独调优和分布式应用程序的所有力量,以及单一、集成系统的易用性和理解性。
当系统存在超过十年时,就像 Rails 一样,它们的自然趋势是僵化。有无数的原因说明为什么每一次改变都可能对某个人,某处,某个依赖于过去行为的人造成问题。而且这些原因对于个人来说是公平的。
但如果我们过于倾听保守派的声音,我们就永远看不到另一边的景象。我们必须偶尔敢于打破和改变事物,以发展和成长。正是这种演变将使 Rails 在未来的几十年里保持生存和繁荣。
理论上这一切都容易理解,但实践中却很难接受。特别是当你的应用程序因为 Rails 主要版本的向后不兼容的更改而损坏时。正是在那些时候,我们需要记住这个我们珍视的价值,即进步优于稳定,才能给我们力量来调试损坏的部分,找出问题,并跟上时代。
这并不是随意造成不必要或过度的伤害的许可。2.x 到 3 的 Rails 大迁移仍然留在了许多当时在场的人的伤疤组织中。那是一次艰难的迁移。一次严重的动荡,让许多人长时间地停留在 2.x 版本中,一些人甚至被劝说得心灰意冷。但从长远来看,它仍然是值得的。
这些是我们必须继续做出的艰难权衡。Rails 在五年后会因为我们今天的改变而变得更好吗?Rails 在未来几年通过采纳另一个问题领域,例如作业队列或 WebSockets,会变得更好吗?如果是,那么我们就必须忍受并做好这项工作。
这项工作不仅仅发生在 Rails 本身,也发生在更广泛的 Ruby 社区。Rails 应该站在帮助 Ruby 进步的最前沿,通过推动其成员更快地采用较新版本。
到目前为止,我们做得非常出色。从我开始以来,我们已经经历了 Ruby 1.6、1.8、1.9、2.0、2.1、2.2、2.3、2.4、2.5,现在转向 2.6。一路经历了许多重大的变化,但 Rails 一直在那里支持 Ruby,并帮助大家更快地跟上程序。这在一定程度上是 Rails 作为 Ruby 主要推广者所服务的特权和义务。
链条中的辅助工具也是如此。Bundler 曾经是一个有争议的想法,但由于 Rails 坚持将其作为共享未来的基石,如今它已被视为理所当然。对于资产管道和 Spring(持久化命令进程)等事物也是如此。这三者都经历过(或仍在经历)成长的烦恼,但它们长期价值的明显性帮助我们克服了这些。
进步最终主要关乎人和他们推动变革的意愿。这就是为什么像Rails Core或Rails Committers这样的团体没有终身席位。这两个团体都是为那些积极致力于为框架进步的人设立的。对一些人来说,他们对这种进步的投入可能只有几年,我们将永远感激他们的服务,而对另一些人来说,它可能持续几十年。
同样,这也是为什么我们必须继续欢迎和鼓励社区新成员如此重要的原因。我们需要新鲜血液和新想法来取得更好的进步。
Rails 以其许多备受争议的想法为荣,如果要求每个人始终完全服从所有原则,Rails 很快就会变成一个封闭的意识形态隐士团体。所以我们不这样做!
我们需要分歧。我们需要方言。我们需要思想和人的多样性。正是这种思想的熔炉,才能为所有人提供最好的共享空间。许多人贡献他们的意见,无论是代码还是经过深思熟虑的论证。
所以,虽然这个准则描述了一个理想化的形式,但日常现实要复杂得多(也更有趣)。Rails 之所以能够在这样一个大帐篷下支持如此庞大的社区,正是因为几乎没有(甚至没有)严苛的考验。
RSpec 的持续成功,一个我经常表达严重不满的测试 DSL,就是完美的证明。我可以喋喋不休地抱怨为什么我不认为这是正确的方式,但它仍然可以蓬勃发展。这一点更为重要!
同样,Rails 作为 API 的出现也是如此。虽然我个人的重点和奉献是包含视图的集成系统,但对于那些想要预先分发其客户端和服务器的人来说,Rails 无疑还有很大的空间。我们应该拥抱这一点,只要它能够作为次要使命共存,而且我相信它肯定可以。
然而,拥有一个大帐篷并不意味着试图满足所有人的所有需求。它只是意味着你欢迎所有人参加你的派对,并允许他们自带饮料。我们不需要失去我们的灵魂或价值观,就可以邀请其他人加入我们,并且我们可能会学到如何调制一两杯美味的新饮品。
这并非免费。它需要付出努力才能受欢迎。特别是如果你的目标不仅仅是吸引更多与社区现有成员相似的人。降低入门门槛是我们应该始终认真对待的工作。
你永远不知道什么时候,第一个只是修正文档拼写错误的人,最终会实现下一个伟大的功能。但如果你微笑并感谢任何能够激发动力的微小贡献,你就有机会找出答案。