在 Ruby Core 中,"foo"f
已经为 Ruby 2.1 提出了一种新的冻结字符串的文字表示法,但现在人们担心用这种语法编写的代码将无法被 Ruby 2.0 解析。为什么这是个问题?Ruby 不是只尝试向后兼容吗?也就是说,如果用 Ruby 2.0 编写的代码可以被 Ruby 2.1 解释器解析,那还不够吗?为什么用 Ruby 2.1 编写的代码必须能够被 Ruby 2.0 解释器解析?
2 回答
这是一个非常好的问题。我关注核心 ML 有一段时间了,我相信这里的主要问题是新的冻结文字语法是语法变化,而不仅仅是功能变化。
让我稍微扩展一下答案。首先,让我们记住,我们谈论的是次要版本更改,它不应该破坏与以前代码的兼容性。事实上,你可能会争辩说,事实上,这根本不会发生。Ruby 2.0 代码在 Ruby 2.1 中可以正常工作,但不能相反。
您还提到暗示新版本可能包含以前版本中不可用的功能。但我相信这正是担忧开始的地方。
新语法不仅引入了功能更改,还引入了语法更改。这意味着如果您尝试使用 Ruby 2.1 代码提供 Ruby 2.0 解析器,它可能会失败。由于我们已经知道的所有原因(兼容性、迁移、维护等),这可能不是一个好主意。
这与在 Ruby 2.1 中创建一个 Ruby 2.0 不可用的新方法时完全不同。在这种情况下,确实 2.1 会比 2.0 有更多的功能,但是如果你用相同的代码库提供以前的解释器,它就不会抱怨。你没有改变语言语法,你只是丰富了核心库。而且,在这种情况下,很容易使您的 2.0 代码更类似于 2.1:只需实现缺少的方法。
这在语法更改时是不可能的,因为您需要重新实现解析器。
如果您在这一点下查看 Ruby 更改,您会发现在次要版本之间引入了很少的语法更改。
像 stubby lambda、关键字参数、新的哈希表示法这样的变化,它们都被引入了一个重大的颠簸。
一般来说,语法级别的更改与功能级别的更改相比可能会导致更多的维护问题。这是我对新冻结文字语法背后的原因以及他们最终使用.freeze
而不是新语法的原因的解释。freeze
已经存在于以前的 Ruby 版本中,但即使它们带有一个全新的方法,方法也不会在解析时进行评估,并且它们可以很容易地向后移植。
我想到的答案是:
- 从 ruby 2.0 迁移到 2.1 更容易
- 在 ruby 版本之间共享代码
- 人们似乎觉得 f 后缀丑陋/令人困惑
移民
当两个 ruby 版本都可以解析语法时,从 2.0 迁移到 2.1 就少了一项任务。现有代码可能会受益于更好的冻结字符串处理而无需任何更改。
ruby 版本之间的共享代码
使用类似的语法,您可以编写适用于多个 ruby 版本(2.0 和 2.1)的 ruby 代码(尤其是库)。这为库开发人员提供了更多的受众(并且为不同的 ruby 版本维护的版本更少)。然而,图书馆用户可以更轻松地从 ruby 2.0 迁移到 2.1。ruby 2.1 版本仍然可以从更好的冻结字符串处理中受益。
个人品味
阅读 ruby 错误跟踪器,我发现有些人似乎觉得新语法丑陋/令人困惑。这里有些例子:
- “[不使用 f 后缀] 看起来像 Ruby”
- “[f-suffix] 符号很丑陋。”
- “它对字符'f'感到困惑。例如,它提醒'Float'”
- “我个人不喜欢前缀/后缀形式,它们感觉就像 python 中的 u'str'”
- “看起来很奇怪”(好吧,这不是来自追踪器)
还有其他人喜欢新语法。好吧,这是主观的,但我们想知道为什么人们会抱怨,所以这是一个重点:)