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