What's Wrong With Global Variables?

The following text is a partial translation of the original English article, performed by ChatGPT (gpt-3.5-turbo) and this Jekyll plugin:

只有懒惰的人才还没写过关于全局变量有多么邪恶的文章。这个问题始于1973年,当时W. Wulf等人声称“非本地变量是导致程序难以理解的主要因素。” 自那时起,还有许多其他原因被提出,以说服程序员停止使用全局变量。我想我已经读过它们全部,但没有找到最让我困扰的原因:可组合性。简而言之,全局变量使代码难以或不可能以原始作者未预期的方式组合。

最近我在Ruby上使用Sinatra编写了一个Zold的Web前端。这是根据他们的文档启动Web服务器的方法:

在这里,start!App 类的一个静态方法,你需要将其声明为它们默认父类 Sinatra::Base 的子类。为了告诉应用程序监听哪个 TCP 端口,你需要预先配置它。

如果你想要启动两个web服务器,应该怎么办?对于测试来说,这可能是一个非常合理的需求。例如,由于Zold是一个分布式网络,有必要测试多个服务器之间的通信。但我做不到!绝对没有办法。因为Sinatra的设计假设整个应用程序范围内只能存在一个服务器。

这个问题真的能修复吗?让我们来看看他们的代码。Sinatra::Base类本质上是一个单例,不应该有多个实例。当我们调用App.set(:port, 8080)时,值8080被保存到一个单一实例的属性中。无论这些方法是从哪个实例调用的,数字8080都可以在Sinatra::Base的所有方法中使用。

我认为他们没有使用真正的Ruby全局变量,因为他们知道全局变量是不好的。为什么它们不好以及有什么替代方案——他们没有注意到。

从技术上讲,他们的设计是“全局作用域”。Sinatra::Base将整个应用程序视为其可见范围。无论谁调用它,所有东西都是可见的,包括在之前的调用和之前实例化的对象中创建的内容。这个“类”就像一个巨大的全局变量的集合。

每个全局变量都是这种麻烦的制造者。虽然应用程序很小且测试覆盖率低时,全局变量可能不会有问题。但应用程序越大,其自动化测试场景越复杂,就越难以组合依赖于全局变量、单例或类变量的对象。

我的建议是:在任何情况下,甚至不要考虑使用任何全局变量。

Translated by ChatGPT gpt-3.5-turbo/42 on 2023-12-17 at 15:45

sixnines availability badge   GitHub stars