Просмотр полной версии : глобальные переменные зло?
filepark
13.08.2011, 17:07
Вопрос теоретический, есть программа претендующая на некоторую универсальность. Имхо, удобно создать класс исключительно для хранения настроек - статических переменных, констант и функций. Они доступны везде и всегда. Но, я слышал мнение, что это зло и все чайники через это проходят.
Почему это плохо?
Какова альтернатива?
Использовать xml для хранения настроек, имхо, неудобно, его могут изменить/удалить, нужно время чтобы его загрузить.
Если бы это было зло, никто бы не делал такой возможности. Важно решить какие переменные (или константы), стоит хранить глобально, а какие нет.
А хранить глобально можно многое, и зачастую это лучший вариант.
mikhailk
13.08.2011, 17:33
Но, я слышал мнение, что это зло и все чайники через это проходят.
Все очень просто.
Вы делаете глобальный класс, кладете туда кучу публичных переменных, которые произвольно меняете в произвольных местах кода. В какой-то момент получаете хороший головняк от того, что приложение работает нештатно из-за того, что эти глобальные переменные имеют неправильное значение, но кто именно их изменил, совершенно непонятно.
Соответственно, глобально хранить имеет смысл константы и переменные, которые выставляются один раз при загрузке приложения, а затем исключительно считываются.
А, вообще-то, эта тема - злостный баян. Надо в поиск сходить.
Это такой способ мышления, вариант "организации" порядка.. Типа на вопрос "а где у нас..." ответ готов заранее - в шкафу.
Я лично этой логики никогда не мог понять - почему, с какой стати настройки для, например, кнопки, должны храниться в общественном месте и быть доступны всем - текстовым полям, битмапам и прочим левым сущностям? В самой идее "доступно всем и отовсюду" содержится дьявольское зерно Хаоса и полная бессмыслица. Дело не в том, что кто-то злобно поменяет чего-нибудь в чужих настройках. Дело в том, что контроля просто НЕТ. А это значит, что никакой гарантии отсутствия ошибок нет. Это значит, что программист оставил зияющую дыру в структуре ради того, чтобы не напрячь случайно свой мозг обеспечением иерархии и контроля – тем, что и делает из кучи строчек кода Программу.
Я не знаю ни одного случая, когда "зачастую это лучший вариант".
Wolsh, мысли шире. Допустим есть игра на бокс2д (чисто для примера), в ней тебе постоянно надо переводить пиксели в метры, радианы в градусы и наоборот. Не лучший ли вариант хранить формулы для перевода этих величин в глобальных константах? Вот тебе и один случай
saikspaik
13.08.2011, 19:58
filepark
Среди программистов тоже встречаются суеверные, вот они и боятся использовать глобальные переменные :D
Я считаю так - если тебе удобно использовать глобальные переменные - используй, чего огород городить? Не удобно, или дядька начальник запрещает - не используй.
А если говорить о традициях, то таки да - глобальные переменные - зло!!!
Имхо, удобно создать класс исключительно для хранения настроек - статических переменных, констант и функций. Они доступны везде и всегда. Но, я слышал мнение, что это зло и все чайники через это проходят.
Почему это плохо?
Какова альтернатива?
Использовать xml для хранения настроек, имхо, неудобно, его могут изменить/удалить, нужно время чтобы его загрузить.
Я бы сказал не "Почему это плохо" (ведь Вы используете и проблем не возникает), а "на что можно напороться".
- например появится 2-я часть системы, которую надо настроить по другому - а конфиг один (не важно xml или статический класс)
- замучаетесь менять эти глобальные переменные до теста и после автоматического теста возвращать "как было", хотя, вроде делают так и не жужжат.
- если речь идет не просто о постоянных данных конфигурации, а о некоторых параметрах состояния хранящихся глобально - то тут еще возникает путаница "... да ёлы палы, какая сволочь эту переменную меняет, я же выставляю false, а здесь она опять true"
Как бороться?
- протаскивать параметры
- протаскивать объекты с параметрами
- протаскивать фабрики, которые правильно параметризуют создаваемые ими объекты
- протаскивать фабрики фабрик
- использовать IoC-контейнеры
- ...
но на самом деле, будет только хуже.
mikhailk
13.08.2011, 20:25
Я не знаю ни одного случая, когда "зачастую это лучший вариант".
Например, есть типовой клиент, который запускается в разных сетях, причем в продакшн- и тест-модах. Разумно (на мой взгляд) все настройки для всех сетей свести в один статический класс. При этом, после запуска клиента в нем же запомнить текущий вариант запуска. Далее, в ходе показа интерфейса пользователю мы должны подгонять функционал под особенности текущей социальной сети. Мне кажется простым и удобным решением иметь всегда под рукой (глобально доступными) ApplicationConfig.appMode и ApplicationConfig.socialNetwork. В противном случае мне потребуется передавать эти параметры сквозным образом и я не вижу, что я от этого выиграю. Плюс, может оказаться, что портировании в очередную сеть мне потребуется иметь настраиваемый интерфейс на пятом-седьмом уровне иерархии - придется модифицировать все классы, чтобы дотянуть туда appMode и socialNetwork. В чем выигрыш по сравнению с глобальными параметрами?
На мой взгляд, тут как всегда, главная часть любого инструмента - голова его владельца.
goodguy, в моем тексте нет ни слова о константах. Как и в названии темы.
expl, то, что Вы называете "протаскивать", обрисовывает ситуацию, когда архитектура заточена под глобальные переменные, и вдруг Вы решили эти глобальные переменные отменить. А проект уже написан, и Вы начинаете "протаскивать", не спорю. Но когда архитекрура строится изначально иерархически, вложенными модулями, этот процесс естественен и называется настройкой при инициализации. Когда каждому более глубоковложенному модулю передаются все те параметры, которые ему необходимы, чтобы настроить себя и свои составляющие, точно так же при вызове метода (передаче команды этому модулю) ему отдаются необходимые параметры. Это аналог положения метода в классе - Вы можете хранить всё и вся в приватных полях класса, доступных всем методам, и вызывать методы с пустым приемником: foo(); а можете хранить только то, что действительно нужно (например для хендлеров и геттеров/сеттеров), а методы вызывать, передавая им локальные данные: foo(w, h, index); Оба варианта работают, это просто вопрос логики – глупо создавать поле класса лишь для того, чтобы передать данные из одного метода класса в другой, и при этом не быть уверенным, что это значение в поле класса не будет переписано из другого метода до того, как попадет "по назначению". Представьте, что этот класс потребовалось расширить новой функциональностью – где гарантия, что, добавляя новые методы, Вы учтете все связи, что были раньше построены на хранении промежуточных значений в поле класса? И это те же самые архитектуры, на уровне класса показывающие то же, что творится в проекте. ООП предлагает использовать заведомо безопасное решение, чтобы исключить возможность ошибки еще на стадии планирования. Аргументы типа "но я же помню че кого" и "да кому надо там чето менять" выглядят, простите, как детский лепет. Нет смысла задумываться о верной архитектуре, если вы делаете банер. Но если от вашей лени будет зависеть безопасность игроков или денег пользователей, стоит прислушаться к тому, что советуют профессионалы. ООП выглядит смешно и монструозно на проектах "одеть куколку" (привет Сандерсу / Кумаранатунгу). Но когда вы планируете что-то динамическое и развивающееся, от него не скрыться.
Разумно (на мой взгляд) все настройки для всех сетей свести в один статический класс.Что разумного иметь настройки всех сетей в приложении, выложенном на Facebook? Я начинаю бояться за свой рассудок.
mikhailk
13.08.2011, 21:41
Что разумного иметь настройки всех сетей в приложении, выложенном на Facebook? Я начинаю бояться за свой рассудок.
Это открытая информация, ее можно получить без декомпиляции клиента. Адреса API-серверов соцсетей, адреса собственных серверов, appID приложений. Клиент при загрузке проверяет переданный ему сетью appID и настраивается на сервера, соответствующие этому appID. Не вижу дополнительных проблем (клиенты все равно декомпилят, в сервера все равно долбят и без этого).
Но когда архитекрура строится изначально иерархически, вложенными модулями, этот процесс естественен и называется настройкой при инициализации. Когда каждому более глубоковложенному модулю передаются все те параметры, которые ему необходимы, чтобы настроить себя и свои составляющие, точно так же при вызове метода (передаче команды этому модулю) ему отдаются необходимые параметры.
Это все больше теория, насчет того, что все параметры можно предусмотреть заранее, на этапе проектирования. На практике приходится при таком подходе либо тащить сверху вниз какие-нибудь xml-данные (и расширять их по мере необходимости узлами/атрибутами) или, что дает большую свободу, объект-обертку для параметров, который расширять путем добавления новых свойств.
И все равно я не понял, что я выигрываю от того, что протаскиваю по всему приложению ApplicationConfig.appMode и ApplicationConfig.socialNetwork, вместо того, чтобы работать с ними как с глобальными данными.
Вобщем, я так понял, никто не считает проблемой наличие никому не нужных данных или данных, доступных всем, кому они не нужны. "Разумно" - не то слово, которое приходит мне на ум, ну да ладно. "Лишь бы работало!" - так ведь? Я сбоку постою, не люблю демонстрации.
mikhailk
13.08.2011, 22:01
Глобальная доступность константы Math.PI не очень смущает?
И все равно я не понял, что я выигрываю от того, что протаскиваю по всему приложению ApplicationConfig.appMode и ApplicationConfig.socialNetwork, вместо того, чтобы работать с ними как с глобальными данными.
А зачем всему приложению знать в какой социальной сети оно находится? Имхо, должна знать только обертка(iFrame например) приложения, которая и сообщает только лишь необходимые данные о соц. сети. Например возможено ли создание своих альбомов с картинками или нет.
mikhailk
13.08.2011, 22:12
А зачем всему приложению знать в какой социальной сети оно находится?
Настройка элементов интерфейса в основном.
Разные валюты, разные размеры фото, разный функционал.
Но все равно, мы приходим к единственному аргументу: "ApplicationConfig.socialNetwork - плохо, потому что общедоступно".
Других аргументов я что-то не вижу. :)
Но я его, собственно, и задумал как общедоступный, чтобы он всегда был под рукой.
mikhailk, Вам тоже стоит вступить в клуб "я читаю название топика, прежде чем участвовать в споре". И все же отвечу - нет, не смущает меня константа Math.PI, зашитая в плеере еще со времен МХ наверное, когда об ООП в ActionScript только мечтали. Ее использование не создает сильной связности. Если я когда-нибудь допишу свою графическую библиотеку, использующую класс Math направо и налево, и Вы ее скачаете, Вам не придется бегать по всему интернету в поисках этого класса. Но я не смогу воспользоваться вашим классом, которому для работы кровь из носу нужен другой класс – ApplicationConfig, а не простые настройки инициализации.
Приведите аргумент какой-нибудь, а то я уже не понимаю с чем спорю. "ApplicationConfig.socialNetwork - хорошо, потому что общедоступно". Это всё? А есть какое-нибудь объяснение, почему "общедоступно – это хорошо"? Так сказать, по сути спора?
Разные валюты, разные размеры фото, разный функционал.
...разные приложения.
Мое мнение по теме. Если есть возможность (разумная) избавиться от глобальности - к этому нужно стремиться. Как уже было сказано выше, многое при этом решается еще на этапе проектирования. Как уже было сказано выше, публичные переменные доступны всем, бери - не хочу, делай что хочешь. Другое дело геттеры/сеттеры, даже скорее только геттеры - показать покажу, а испортить не дам. Это инкапсуляция, это ООП. Если же нужно что-то супер-глобальное, почему бы не использовать статику? Но это уже другая тема.
mikhailk
13.08.2011, 23:20
Вобщем-то, спора никакого нет.
Я так сделал для собственного удобства. Наличие статического класса ApplicationConfig и публичной переменной socialNetwork позволяет мне при необходимости сделать быструю доводку интерфейса под конкретную сеть, в т.ч., в тех классах, которые изначально не планировались к настройке под сеть, т.е. параметры соцсети в них изначально не передаются, а значит надо их тащить туда дополнительно. Где-то через конструкторы, где-то через дополнительные методы.
Соответственно, мой аргумент прост как 5 копеек: удобство за счет незначительного послабления в части строгости ООП.
Добавлено через 3 минуты
Другое дело геттеры/сеттеры, даже скорее только геттеры - показать покажу, а испортить не дам
Я с клиентом работаю один.
Если бы над проектом работала группа программистов, я бы реализовал через сеттер/геттер. В момент загрузки клиента вычислялся бы параметр сети, который потом де-факто становился бы константой.
Я говорил не о программистах. Скорее о человеческом факторе. Но когда работаешь один, действительно, многие проблемы кажутся... Кажется что их нет. Проект при этом может быть успешным и различные доработки нисколько не напрягают (в контексте темы) единственного кодера.
Ладно, немного сбавим градусы.
Мне просто интересно, в практическом смысле, вот Вы создали скажем класс, способный выводить сообщение юзера с его фотографией, датой и прочим. И Вам не жалко сделать его инвалидом, хватающимся за некий левый ApplicationConfig с набором стилей? Ведь это не позволяет Вам использовать этот классик повторно в другом проекте as is. Как Вы с этим живете?
mikhailk
13.08.2011, 23:51
И Вам не жалко сделать его инвалидом, хватающимся за некий левый ApplicationConfig с набором стилей? Ведь это не позволяет Вам использовать этот классик повторно в другом проекте as is. Как Вы с этим живете?
С замечанием абсолютно согласен. Эти классы не используются вне приложений для соцсетей, а все приложения для соцсетей имеют одинаковую структуру и обязательно содержат ApplicationConfig.
expl, то, что Вы называете "протаскивать", обрисовывает ситуацию, когда архитектура заточена под глобальные переменные, и вдруг Вы решили эти глобальные переменные отменить. А проект уже написан, и Вы начинаете "протаскивать", не спорю. Но когда архитекрура строится изначально иерархически, вложенными модулями, этот процесс естественен и называется настройкой при инициализации. Когда каждому более глубоковложенному модулю передаются все те параметры, которые ему необходимы, чтобы настроить себя и свои составляющие, точно так же при вызове метода (передаче команды этому модулю) ему отдаются необходимые параметры
Кстати да, поспорить особо не с чем, иерархия рулит.
Но в промежуточных по иерархии классах может появляется код который только передает общие объекты к младшим.
Вот эти младшие ссылались бы на глобальный синглтон, например.
Тут все определяется уверенностью в том что, не потребуется 2-й логгер, например(их обычно глобальными делают, хотя даже логгер мне таки потребовался второй на текущем проекте)
На самом деле я не фанат глобальных вещей.
Потому что в один прекрасный момент младшему объекту потребуется передать параметр в зависимости от того, кому он принадлежит - всё! Глобальные точки доступа можно выкидывать и чесать репу.
Очередная тема, которая приведет к холивару )
Вообще не понимаю тех, кто утверждает что глобальные переменные приводят к связанности, и тут же говорят, что нужно протягивать свойства до нужного места. Вот это, по-моему, как раз и есть связанность, ведущая к полнейшей неразберихе.
здесь под связанностью имеется в виду зависимость объекта не от непосредственного класса его содержащего или манипулирующего им, а опосредованная зависимость от классов уровня приложения.
То есть объект получается связанным, сросшимся с конкретным приложением, его конкр. структурой.
Вот это - не комильфо.
Честно, ничего не понял из вышесказанного )
То есть объект получается связанным, сросшимся с конкретным приложением, его конкр. структурой.
Если свойства протянуть везде до нужных мест, эта структура так же будет целиком и полностью сросшаяся с конкретным приложением.
эта структура так же будет целиком и полностью сросшаяся с конкретным приложениемНичего подобного. Класс будет получать настройки обычным способом, через сеттеры или параметры конструктора, и легко может быть использован сам по себе в другом проекте или другом контексте, как верно подметил expl. Если же класс содержит импорт класса-провайдера настроек, чтобы запросить у него данные, Вы не можете использовать его как есть, без этого другого класса. Это и называется сильной связностью – когда один класс требует для работы создание определенной среды, других жестко определенных вышестоящих классов (читай - подстройки всего приложения под себя). Вместо того, чтобы передать этому блочку текст, стиль, картинку и размеры, Вы импортите в него статический провайдер, хранящий настройки для всего и вся в приложении, и учите его "звонить в штаб". Соответственно ни в каком другом проекте этот класс работать не сможет, пока Вы не соберете для него этот Штаб и не настроите его так, чтобы он (штаб!) умел удовлетворять ваш капризный классик.
При "каскадной" инициализации Вы передаете экземпляру только то, что нужно конкретно ему (естественно, включая то, что нужно для инициализации его детей-составляющих, если они есть). Класс ни к чему не привязан. Он не требует наличия команды поддержки. В этом смысл "абстракции"/самодостаточности и "инкапсуляции". Да, он тоже требует параметров для настройки. Но, в отличие от штабиста, он требует ТОЛЬКО то, что ему нужно, и не требует ИСТОЧНИКА, а только сами данные. Поэтому неважно, в каком проекте он используется, ему надо только размеры, стиль, текст и картинку, но не структуру, отдающую эти данные. Вам не надо городить для него специальных точек доступа ВЫШЕ этого класса, выискивая в его коде, кого и за какие сиськи он будет дергать во время работы, вам надо передать нужные настройки в публичные точки доступа самого этого класса, и все. Это "универсальность" и "повторное использование". Почитайте уже ООП. Пора.
mikhailk
14.08.2011, 20:32
Смотрю, флейм никак не остановится. :)
Давайте уж говорить конкретно - не только про выигрыш, но и про затраты.
В условиях, когда приложение развивается по диздоку, который пересматривается постоянно (конкуренты, желания пользователей, тестирование игровых технологий и пр.), мы не знаем заранее, где и когда нам потребуется что-то настраивать в зависимости от параметров приложения, поэтому, если хотим остаться в рамках корректного ООП (т.е., отдаем всем объектам только то, что им положено знать), мы влетаем в очень большие издержки по модификации кода каждый раз, как только появляется необходимость передать новый параметр сверху в самый низ.
Вариант с объектом-оберткой для всех параметров AppSettings (или как-то так), который мы закладываем на этапе проектирования и передаем всем сверху вниз через конструкторы, позволяет минимизировать затраты по доработке, но нарушает правило, что каждый получает только то, что должен, значит корректным признан быть так же не может.
ЗЫ. По поводу реиспользования кода - мне искренне хотелось бы посмотреть на реиспользование окна банковских операций по переводу валюты соцсети в игровую валюту в приложениях, не связанных с социальными сетями. Но это так, реплика из зала.
mikhailk, goodguy, вы просто не постигли Дао
mikhailk
14.08.2011, 21:08
mikhailk, goodguy, вы просто не постигли Дао
Я что-то такое подозревал. :D
Аа, так вон оно в чем дело :D
Не, а по большому счету я согласен с Wolsh'ем, и сам использую иногда глобальные переменные только из лени ) В серьеных проектах всегда исползьзую подход описаный Волшем
Мне кажется все зависит от проекта, ведь реализовать любой проект можно по разному, в зависимости от нужд и удобства.
Вот например, недавно делал приложение, показывающее некие списки, данные в которых постоянно меняются с сервера. Ну и более в приложении ничего небыло. Так вот сами списки - есть ни что иное как нарисованная кодом графика, и тут я использую класс глобальный переменных, - зачем? Ну захотелось мне сменить ширину блока, высоту, или просто цвет,( градиентный например ), с одной стороны - можно и в коде поменять, да фигня, а с другой стороны если graphics идет следующим образом типа moveTo, lineTo и т.д. раз 100 ( ну красивую я фигуру рисую - ок ) , то проще изначально поменять внутри этих мувов и лайнов, на глоб константу, и теперь в любой момент я получу нужный мне скин сменив только 2 строчки, не гробя весь код, с другой стороны эти переменные можно и в классах зашивать и там уже тоже менять по 2 строки да и все. Ну а если у нас несколько не взаимосвязанных классов, которые реализуют графику приложения ? В каждый класс лезть , искать и править по 2 строчки, когда проще открыть конфиг файл и в нем все сразу и поправить? Имхо - тема холиварная, из оперы - МВС или не МВС, каждый пишет как ему удобнее, главное чтобы это конкретно не было Быдлокодством, ну а чуть чуть можно :D
Глобальным в принципе может быть то, что не нужно менять (т.е. не переменные), а функции, например, которые не зависят от контекста (parseInt - в любом месте программы должна делать одно и то же и всегда вернет один и тот же результат, буде один и тот же ввод). Цифры :) символы строк, элементы энумераторов и т.п. могут быть глобальными т.как нет смысла делать 2 разных. Там, где в принципе может быть два разных, глобальные лучше не делать.
Если вы хотите немного глубже понять проблему - есть такой тезис, что переменные, вообще, как таковые - один из главных источников ошибок программ. Т.о. существует понятие программ без побочных эффектов - очень грубо говоря, программ, в которых переменные не используются в принципе (в теории, так можно действительно написать любую программу, но это очень непрактично). В любом случае, количество переменных нужно стараться сводить к минимуму т.как переменные хранят состояние, а это значит, что функции становятся зависимыми от состояния и на ваши плечи ложится ответсвенность за то, чтобы протестировать функции во всех возможных состояниях, что, очень часто не возможно в принципе. Но вы можете с этим бороться сводя область использования каждой конкретной переменной к минимуму - таким образом уменьшая количество вариантов, которые нужно тестировать, и, таким образом, вы пишете более надежный код.
в теории, так можно действительно написать любую программу, но это очень непрактично
Я бы посмотрел даже на саму простейшую программу без переменных ))) Ну не считая такую public class Main extends Sprite
{
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
}
saikspaik
15.08.2011, 02:29
Уже пошло as-кунг-фу. :D
Например функцию вычисления факториала, можно написать без переменных?
Да не ну бред яж сказал) Просто wvxvw товаришь начитанный, умный, давно на форуме, и как говорится не лыком шыт, но в данный момент - его слова стоят под глубочайшим сомнением))) Хотя меня коробит слово в ТЕОРИИ , может он и хотел сказать , что в теории и бог существует, только его никто не видел
Господа. Может, всё таки, потрудитесь открыть новую тему для выяснения этого вопроса? Вы название темы то читали?
@wvxvw. Не уверен, что всё понял. То есть ты считаешь, что контекстная зависимость объектов, в случае с глобальными полями, и "мусор" в родительских объектах при протаскивании данных в дочерние - это вопросы "десятые", так? Главное - сохранять контроль над изменением значений переменных (параметризующих приложение, например)?
Т.о. существует понятие программ без побочных эффектов - очень грубо говоря, программ, в которых переменные не используются в принципе
Эрланг, в теории не использует переменных вообще - это его фишка. Правда на реализации связи с сервером и БД - пришлось немного этим поступиться и глобальные псевдопеременные всё же есть там.
Функция принимает одни параметры и возвращает другие. Переменных в языке нет вообще - только константы.
Например функцию вычисления факториала, можно написать без переменных?
да
fact(0) -> 1;
fact(N) -> N * fact(N-1).
аналог (не проверял, написал тут прям)
public function factorial(n:uint):uint{
if(n==0) return 1;
else
return n*factorial(n-1);
}
Переменных нет - только параметры - Я думаю разница между этими двумя понятиями ясна.
Да, это в принципе особенность всех декларативных языков такого плана, Erlang, ML (и наследники CaML / Obj-CamML), Scheme и т.п. в них не используются переменные. Если вы будете размышлять логично, то значение любой вашей переменной вычисляется (т.е. его можно описать функцией), либо задается один раз (константа). Проблема которую решают переменные заключается в том, что иногда не практично много раз вызывать функцию (т.как результат уже один раз был получен). Но, хороший код старается избегать повторных вызовов функций (конечно, иногда это неизбежно), но, тем не менее, к этому нужно стремится :)
fish_r:
Это теория немного другого плана, отношение к глобальным переменным в ней - это следствие (одно из). Следуя ей, естесственным образом не будет возникать проблем с глобальными переменными т.как контекст переменной будет всегда определятся областью, в которой она может быть только одна, и, естесственным образом же, не будет возможных конфликтов, когда `кто-то неизвестный меняет значение'. Но это теория, а не практическое руководство к действию. Ее нужно осознать и сделать максимально похоже :)
saikspaik
15.08.2011, 15:28
Переменных нет - только параметры - Я думаю разница между этими двумя понятиями ясна.
Суть - одно и то же.
Вот сдесь:
public function factorial(n:uint)
Фактически создается переменная n, разве нет?
carrotoff
15.08.2011, 15:32
Фактически создается переменная n, разве нет?
Нет, здесь передается именно параметр. Это такое значение, которое в теле функции меняться не будет.
От параметра зависит результат работы функции, но сам он остается неизменным.
carrotoff да ну нафиг?
public function factorial(n:uint) {
n = 500;
trace(n) // 500
Это потому что во флеше есть разрушающее присваивание, которое, вообще делает переменные возможными, в том же Erlang'e его нет. И еще во флеше нельзя описать, например:
void foo(baz* const bar) { ... } а в том же Erlang'e так, можно (но это код на С++, чтобы было понятнее).
а в том же Erlang'e так, можно
Скорее только так и можно. Параметры функции - суть константы. Менять их нельзя и ничего специального для этого прописывать не надо.
На первый взгляд, кажется, что это убогость языка, но люди знакомые с понятием юнит-тестирование сразу поймут в чём прелесть такого подхода.
carrotoff
15.08.2011, 16:28
in4core, суть не в том, что это работает или нет, а в том, что эта операция абсолютно бессмысленна и не нужна.
carrotoff да ну нафиг опять? ))
function a(n:int) {
// рассматривается в случает нет переменных
if( n > 100 ) n = 100;
else if( n < - 500 ) n = n*2;
else 'ok';
superOtherMethod(n);
}
in4core ломает фундаментальные устои программирования.
carrotoff да ну нафиг опять? ))
Да придет спаситель)
carrotoff
15.08.2011, 17:40
in4core, ну, раз уж такое дело пошло, то на спор и жестче (http://govnokod.ru/) можно написать! Не хочется рассматривать подобные случаи.
Если вы действительно так пишите, то ваш код - настоящий АДЪ. Почитайте что-нибудь о структурировании кода, например, это (http://www.ozon.ru/context/detail/id/6733562/).
in4core ломает фундаментальные устои программирования. Да нет же)) я не хочу сказать, что так надо делать и это хорошо. Я пояснил по факту, что такое может быть и оно может быть в контексте приемлемо для определенной части функционала
Добавлено через 1 минуту
carrotoff у меня давно уже более менее чистый код, когда нет спешки и не работаешь на отбалдысь)
carrotoff
15.08.2011, 17:43
А никто и не говорил что так нельзя сделать. Этого не нужно делать!
Ну понятно что не нужно. спор только изначально шел о том, что НЕЛЬЗЯ - яже доказал что можно. непонятно в чем холивар
carrotoff
15.08.2011, 18:23
сомнительное доказательство, потому как я тоже смогу доказать, что ходить в туалет мимо цели возможно, но кто меня поймет?:)
Хм тогда и надо было сказать МОЖНО - но не нужно) а не категорично. Ну а вообще с другой стороны, мой пример ( если убрать superMethod) вполне адекватен.
например описывается какое то жуткое жвижение или что то в этом духе
function a(n:int):Number {
if(n > 100) n = n%10 / (n*3 + n%2);
else n = 500 * (n^7) ;
return n;
}
saikspaik
15.08.2011, 18:58
сомнительное доказательство, потому как я тоже смогу доказать, что ходить в туалет мимо цели возможно, но кто меня поймет?:)
Все поймут, ходить мимо цели возможно, разве нет?
Так и с переменными - менять можно, а нужно или нет, вопрос другой.
Если бы было нельзя, ВОПРОС бы не стоял, так?
Разговор глухого со слепым.
Я говорил о том, что можно написать вычисление факториала без помощи переменных - и есть языки где переменных нет вообще. То, что в AS3 аргументы(параметры) являются переменными не отрицает подхода, когда их используют как константы.
Я говорил вообще в контексте общей темы. что ОБЩИЕ переменные, на которые могут влиять несколько объектов, а тем более глобальные, плохо вяжутся с безопасным программированием и программированием через TDD. Для этих подходов наилучшая концепция - отказ от переменных (или хотя бы отказ от нелокальных переменных, про глобальные вообще молчу)
Придется опять во флейм поселить. Кто снова выпустит — тот редиска.
Работает на vBulletin ® версия 3.7.3. Copyright ©2000-2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 1999-2008 Flasher.ru. All rights reserved.