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 году, когда В. Вулф и др. заявили, что “нелокальная переменная является основным фактором, влияющим на сложность понимания программы”. С тех пор было предложено много других причин, чтобы убедить программистов прекратить использование глобальных переменных. Я думаю, прочитал их все, но не нашел ту, которая беспокоит меня больше всего: композицию. Вкратце, глобальные переменные делают код сложным или невозможным для композиции в способы, отличные от того, что ожидал его первоначальный автор.

Недавно я писал веб-интерфейс для Zold на Ruby, используя Sinatra. Вот как начинается веб-сервер в соответствии с их документацией:

Здесь start! - это статический метод класса App, который вы должны объявить как потомок их предопределенного родительского класса Sinatra::Base. Чтобы указать приложению, на каком TCP-порту слушать, вам необходимо предварительно настроить его.

Что делать, если вы хотите запустить два веб-сервера? В целях тестирования это может быть вполне логичным требованием. Например, так как 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:46

sixnines availability badge   GitHub stars