LINUX.ORG.RU

Как вы называете переменные и не только?

 ,


1

2

Привет

Есть ли у вас правила именования переменных и не только для следующих кейсов?

Case 1. Предположим есть некие объекты. Есть функция, которая должна что-то сделать с объектом, например вызываем её вот так: fn(obj). Как понять, аргумент функции - сам объект, указатель на объект, или индекс объекта в каком-то массиве? А как на счет массива индексов? Я понимаю, что можно посмотреть объявление obj (в тех языках, где оно есть), но если это посредине кода, то хочется как-то понять из имени: облегчило бы чтение кода. Думал про obj/iObj/pObj или obj/obj_i/obj_ptr, но может есть лучшие идеи?

Case 2. Функция-член класса. Как по имени различить локальные переменные, глобальные переменные, переменные-члены класса?

Case 3. У вас есть правила именования, которые бы по имени позволяли различать переменную, тип, класс, функциу, макрос и т. п? Я пока переменные называю с маленькой буквы, функции - с большой, макросы - все большие, а вот типы/классы пока называют TType и CClass, но у многих это вызывает отвращение. Варианты получше есть?

★★★★★
Ответ на: комментарий от anonymous

фраза «глобальные переменные — зло» означает «это какое-то говно, потому, что я ниасилил»

Нет, она означает, что их область применимости крайне мала, а шансов выстрелить в ногу полно

annulen ★★★★★
()

Отличная темка, поржал :)

den73 ★★★★★
()
Ответ на: комментарий от XMs

Кроме повышенной связности кода есть еще куча проблем, не менее важных

annulen ★★★★★
()
Ответ на: комментарий от deep-purple

«глобальные переменные — зло» [skip] Я хочу узнать причины, по которым она появилась

Для начала можно посмотреть короткую статью в Википедии https://ru.wikipedia.org/wiki/Глобальная_переменная.

Обезьяне ничего не стОит вынести указатель в глобал скоп и/или пробросить дополнительный аргумент в функцию.

Да и глобальных переменных налепить где надо и не надо тоже не стоит. Но речь ведь не об обезьянах, а о программистах.

Кстати, неконстантными указателями и ссылками по возможности (в теории) тоже желательно не злоупотреблять. В теории любая функция или класс должны быть вещью в себе, не обладающей побочными эффектами и не меняющей состояние программы.

aureliano15 ★★
()
Ответ на: комментарий от aureliano15

недостатки: глобальная переменная может быть изменена в любой точке программы, что может повлиять на работу других частей программы.

Как лихо вывернули ПРЕИМУЩЕСТВО (о котором ниже сами и пишут) в недостаток.

Но речь ведь не об обезьянах, а о программистах

Вот именно! Глобалов они испугались.

deep-purple ★★★★★
()
Последнее исправление: deep-purple (всего исправлений: 1)
Ответ на: комментарий от tailgunner

побольше

Не побольше, а столько, сколько надо.

Остальным в глобале делать нечего

deep-purple ★★★★★
()

Некоторое время назад мне дали один очень умный совет: использовать венгерскую запись для людей вместо традиционной системной венгерской записи. Вот этот камент.

aureliano15 ★★
()
Ответ на: комментарий от deep-purple

недостатки: глобальная переменная может быть изменена в любой точке программы, что может повлиять на работу других частей программы.

Как лихо вывернули ПРЕИМУЩЕСТВО (о котором ниже сами и пишут) в недостаток.

В теории любая функция или класс должны быть вещью в себе, не обладающей побочными эффектами и не меняющей состояние программы.

Разумеется, чрезмерный фанатизм плох во всём. Иногда глобальные переменные нужны. Но злоупотреблять ими не следует.

aureliano15 ★★
()
Ответ на: комментарий от aureliano15

Иногда проброс вложенных аргументов нужен. Но злоупотреблять им не следует.

Починил.

Любую архитектурную «тактику» можно признать опасной или злоупотребительной. Но только в конкретно разбираемых случаях. Поэтому фраза «глобальные переменные — зло» вне контекста не значит ничего, кроме слепой веры в чей-то давний пук в отношении к неизвестному нам коду.

deep-purple ★★★★★
()
Ответ на: комментарий от deep-purple

Поэтому фраза «глобальные переменные — зло» вне контекста не значит ничего, кроме слепой веры

Нет, она значит что человек участвовал в больших и сложных проектах.

anonymous
()
Ответ на: комментарий от deep-purple

Поэтому фраза «глобальные переменные — зло» вне контекста не значит ничего, кроме слепой веры в чей-то давний пук в отношении к неизвестному нам коду.

Есть общие рекомендации по стилю программирования, так, чтобы было и безопасно, и читабельно, и эффективно. Но иногда, чтобы получить более безопасный и читабельный код, приходится жертвовать эффективностью, а чтобы получить эффективный код — жертвовать безопасностью и отчасти читабельностью. Поэтому общие рекомендации не могут помочь во всех случаях. Однако в большинстве случаев они помогают, позволяя достичь разумного компромисса. И рекомендация не использовать глобальные переменные — одна из таких общих рекомендаций. В этом смысле она очень даже многое значит. Но если пользоваться ею бездумно, как заповедью, то, конечно, всё можно довести до абсурда.

Любая теория подразумевает обобщения. Без обобщений не может быть теории. А без теории невозможно обобщить накопленный опыт. Однако в любой теории бывают исключения, и об этом тоже надо помнить.

aureliano15 ★★
()
Ответ на: комментарий от anonymous

человек участвовал в больших и сложных проектах

Т.е. «большой и сложный» это завуалированно: «говнокод забагованый»? Иначе он бы не спотыкался о глобалы и не плевался таким опытом.

deep-purple ★★★★★
()
Ответ на: комментарий от aureliano15

рекомендация не использовать глобальные переменные

Чтобы оно попало в рекомендации, в основной своей массе, обезьяны программисты должны были не мочь остановиться и глобалить направо и налево.

Кстати, за это: Ranged for vs Indexed for (комментарий) спасибо. Всегда думал что так правильно, но не мог обосновать.

deep-purple ★★★★★
()
Последнее исправление: deep-purple (всего исправлений: 1)
Ответ на: комментарий от deep-purple

рекомендация не использовать глобальные переменные

Чтобы оно попало в рекомендации, в основной своей массе, обезьяны программисты должны были не мочь остановиться и глобалить направо и налево.

Именно так они и делали на заре it-эры. Именно поэтому появились процедурные языки и подобные рекомендации.

aureliano15 ★★
()
Ответ на: комментарий от aureliano15

Именно так они и делали на заре it-эры

Т.е. говнокодили. И им, за нехоженые тропы, простительно. Но, судя по комментарию анонима про «большой и сложный», сейчас основная масса продолжает делать так же (не могут остановиться и глобалят направо и налево). Так пусть распишутся в некомпетентности. Ах, да — уже расписались, спрятавшись за фразу «глобалы — зло».

Именно поэтому появились процедурные языки и подобные рекомендации

Языки никак не способствуют отказу от глобалов или ограничению их использования. Обсуждаемая нами рекомендация провальна, ведь о глобалы спотыкаются до сих пор.

Глобалы не зло, совершенно. Знать о них и использовать их можно и нужно. Отцы должны учить как работать с глобалами правильно, чтобы не отстрелить себе ногу, а не воспитывать страх перед ними вот этими рекомендациями. Волков бояться — в лес не ходить.

deep-purple ★★★★★
()
Ответ на: комментарий от deep-purple

Языки никак не способствуют отказу от глобалов или ограничению их использования.

Очень даже способствуют. Именно с появлением процедурной парадигмы программирования народ начал разбивать большие программы на небольшие подпрограммы, локализуя в них переменные.

Отцы должны учить как работать с глобалами правильно, чтобы не отстрелить себе ногу, а не воспитывать страх перед ними вот этими рекомендациями.

Так отцы именно так и учат. А кто как понимает — его дело.

aureliano15 ★★
()
Ответ на: комментарий от aureliano15

народ начал разбивать большие программы на небольшие подпрограммы

Функциональщина — не результат борьбы с глобалами. Из тела функции глобалы всё равно видны. Она «охраняет» только собственный скоп.

локализуя в них переменные

Просто к слову: этого можно было добиться неймспейсами, в том числе и самобытными — префиксы имён. В те времена и возможности — самое оно.

А кто как понимает — его дело

Ну вот большинство плохо понимает, до сих пор. Не значит ли это, что их учат не правильно (только бояться)?

deep-purple ★★★★★
()
Ответ на: комментарий от XMs

Ты так защищаешь глобалы, будто сам их изобрёл

Нет, я просто дискутирую.

Чего у тебя так подгорает?

Не подгорает. Было дело, спрашивал у людей как лучше сделать. Предлагали разное, но все кричали «только не глобалы». С глобалами, как я и думал, оказалось проще, короче и менее запутанно.

Вот, подумал, надо тут сегодня слегка за глобалы потопить, чтобы народ таким категоричным не был ))

deep-purple ★★★★★
()
Ответ на: комментарий от Kroz

Так *_t тебе тоже нельзя, афаир.

anonymous
()
Ответ на: комментарий от deep-purple

Из тела функции глобалы всё равно видны. Она «охраняет» только собственный скоп.

Разумеется. Если бы из тела функции глобальные переменные не были видны, то смысла в них вообще не было. Такой язык просто не использовал бы глобальных переменных. Попытки такие были. Взять тот же лисп. Но ничего хорошего из этого не вышло. Даже в лиспе динамические глобальные переменные всё равно есть.

локализуя в них переменные

Просто к слову: этого можно было добиться неймспейсами

Неймспейсы не локализуют переменные, а всего лишь уменьшают вероятность конфликта имён, да и то не на 100%. И, имхо, неудобств от них больше, чем фич. Куда проще не объявлять в своей программе глобальных переменных с именами cin и cout, чем в каждом модуле писать using namespace std либо в каждой строчке std::cin вместо просто cin. Если же кто-то решит воспользоваться этой «фичей» и объявить в собственном пространстве имён свою cin, то это будет вообще ад.

в том числе и самобытными — префиксы имён.

for(deep_purple_i=0; deep_purple_i<deep_purple_n; ++deep_purple_i)

Так, что ли? Имхо, это даже хуже, чем lpszstrpointertozerostring.

aureliano15 ★★
()
Ответ на: комментарий от aureliano15

Даже в лиспе динамические глобальные переменные всё равно есть

Вот и прекрасно. Значит глобалы не только не зло, а без них даже жить не получается.

Так, что ли?

Да, но это было к слову и не хотелось бы вести больше одной ветви за раз. Ну вот... ты уже начал ))

lpszstrpointertozerostring

Если такая хрень встретится дважды в разных местах, когда все переменные глобальны, то, спасут нас с тобой только «deep_purple_lpszstrpointertozerostring» и «aureliano15_lpszstrpointertozerostring»

deep-purple ★★★★★
()
Ответ на: комментарий от deep-purple

Они мечутся между «мы крутые программисты» (что вполне мб правда) и «среди нас 90% обезьяны, которым пока по башке не дашь не поймут». Забей на эти социоправила и пиши как само разумеется. Если ты один, или ты и есть проект, то важно только твое удобство. Если тобой командуют, то следовать правилам. Если командуешь ты, то лучше не ходи в низкое айти вообще.

anonymous
()
Ответ на: комментарий от anonymous

Оно будет требовать устаровки на клиент. qtcreator через sshfs вдобавок люто тормозит

mittorn ★★★★★
()
Ответ на: комментарий от EXL

Так вот как размножаются люди, использующие венгерскую нотацию.
Линус Торвальдс будет очень недоволен этим тредом.

Лютобешеноплюсую. Тред ужасов.

Stil ★★★★★
()

Прочитал тред...

Похоже сторонники венгерки не знают что можно обходится без неё, а противники, что её можно использовать. Эй, вы пробовали делать как удобнее?

Suntechnic ★★★★★
()
Ответ на: комментарий от deep-purple

Глобалы не зло, совершенно. Знать о них и использовать их можно и нужно. Отцы должны учить как работать с глобалами правильно, чтобы не отстрелить себе ногу, а не воспитывать страх перед ними вот этими рекомендациями. Волков бояться — в лес не ходить.

С одной стороны ты прав. С другой стороны пишу для верстальщиков в гайды вещи вроде «Использование селектора > недопустимо.» и это не потому что этот селектор плохой (или переменные глобальные плохие) и это на самом деле нельзя использовать, а потому что они не умеют и в 1000 раз легче тупо сказать - не используйте это, чем по 20 раз объяснять почему, и какими граблями они мне выстилают дорогу. Поэтому вполне понимаю людей которые могут говорить что глобальные переменные (божественные объекты, синглтоны и Go To) это зло. Это не зло, просто вы (не вы конкретно) не умеете этим пользоваться.

Suntechnic ★★★★★
()
Ответ на: комментарий от aureliano15

using namespace std

Вот одна из вещей которую надо запретить использовать - пишите везде полный путь! using namespace не для того чтобы можно было меньше буковок писать.

Suntechnic ★★★★★
()
Ответ на: комментарий от Suntechnic

Вот одна из вещей которую надо запретить использовать

«Просто вы (не вы конкретно) не умеете этим пользоваться.» (ц)

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

В том то и дело - что я умею. Поэтому и пишу что «using namespace не для того чтобы можно было меньше буковок писать», но большинство думает именно так. А ты потом сидишь внутри файла на овер 2000 строк где с десяток неймспейсов импортировано и гадаешь, от какого неймспейса эта хрень или оно тут вообще локальной функцией запилено.

Suntechnic ★★★★★
()
Ответ на: комментарий от Suntechnic

я умею.

Наверное, для этого в процитированной фразе есть "(не вы конкретно)".

А ты потом сидишь внутри файла на овер 2000 строк

Дальше не читал.

tailgunner ★★★★★
()
Ответ на: комментарий от mittorn

Видно тип даже если использовал auto

Я знал, я знал, авто это извращение.

ya-betmen ★★★★★
()
Ответ на: комментарий от tailgunner

Дальше не читал

Ты небось ищь ни qwidgettextcontrol.cpp, ни gtktableview.c не читал. И куда уж там их править под свои нужды, когда привычка только на три страницы кода набита ;)

anonymous
()
Ответ на: комментарий от anonymous

Ты небось ищь ни qwidgettextcontrol.cpp, ни gtktableview.c не читал.. И куда уж там их править под свои нужды

Скромная гордость лепильщика скульптур из навоза.

привычка только на три страницы кода набита ;)

На две.

tailgunner ★★★★★
()
Ответ на: комментарий от Suntechnic

Нормальная функция здорового мужчины. Она наверняка главное дело делает, в отличие от остального кода с блестками.

anonymous
()
Ответ на: комментарий от tailgunner

Вот тока я могу(мог) запилить любую фичу, скопировав класс и поправив его брутальным способом, и конкретный клиент будет доволен результатом. А трехстраничники так и продолжают говорить низя, формошлёпить и жаловаться друг другу в лифте на отсутствие развития. Как кто-то назовет эти два подхода дело десятое.

anonymous
()
Ответ на: комментарий от anonymous

В этом участке кода она делает вообще все - скачивает xml, парсит его, сохраняет и апдейтит данные БД. А вот склонение слов по числам вынесено в отдельный класс.

Suntechnic ★★★★★
()
Ответ на: комментарий от anonymous

Я брутальный мужик и удовлетворяю клиентов по хардкору, а вы трехстраничные формошлепы

okay.jpg

tailgunner ★★★★★
()
Ответ на: комментарий от Suntechnic

using namespace std

using namespace не для того чтобы можно было меньше буковок писать.

А для чего тогда? Просто другие варианты использования не приходят в голову.

А ты потом сидишь внутри файла на овер 2000 строк где с десяток неймспейсов импортировано

Ну, если с десяток неймспейсов, то импортировать лучше только один — самый частый, или вообще ни одного. А ещё лучше обходиться без неймспейсов. Раньше как-то обходились, и ничего, постоянных конфликтов имён не возникало.

Я сегодня функцию видел на ~635 строк.

В этом участке кода она делает вообще все - скачивает xml, парсит его, сохраняет и апдейтит данные БД.

И зачем так много строк? Не лучше ли разбить парсинг xml и общение с СУБД на разные функции, а внутри выделить и другие функции для выполнения подзадач, связанных с парсингом?

aureliano15 ★★
()
Ответ на: комментарий от aureliano15

А для чего тогда? Просто другие варианты использования не приходят в голову.

Как вариант для сменяемых классов. Ну типа когда у тебя есть \DB\MySql и \DB\Postgress и ту импортируешь нужный в зависимости от бд. Т.е. это нужно тогда когда у тебя в разных неймспейсах спрятаны разные реализации.

А ещё лучше обходиться без неймспейсов.

Смотря где. В Tcl например неймспейсы классные и удобные. Их можно юзать многими разными способами, подниматься и опускаться по ним и т.п. В PHP - да, ни о чем по сути.

И зачем так много строк? Не лучше ли разбить парсинг xml и общение с СУБД на разные функции, а внутри выделить и другие функции для выполнения подзадач, связанных с парсингом?

Хороший вопрос. Я бы даже наверное мог дать координаты этих ребят, чтобы ты мог спросить напрямую, но не буду - не в моих правилах. Как ты понимаешь сам ответить не могу.

Suntechnic ★★★★★
()
Ответ на: комментарий от Suntechnic

Ну типа когда у тебя есть \DB\MySql и \DB\Postgress и ту импортируешь нужный в зависимости от бд. Т.е. это нужно тогда когда у тебя в разных неймспейсах спрятаны разные реализации.

Да, это действительно может быть удобно в некоторых случаях. О таком использовании я не подумал.

aureliano15 ★★
()
Ответ на: комментарий от aureliano15

А ещё лучше обходиться без неймспейсов. Раньше как-то обходились, и ничего, постоянных конфликтов имён не возникало.

Вот я сейчас познаю python... Оказывается это афигительно удобно, когда на каждый импортируемый файл создается свой namespace. Сразу понятно из какого модуля какая функция дергается, сразу решается проблема дубликации имен, и названия функций можно делать максимально простыми.

Возьму себе за практику в С++. Просто в python'е такое поведение из коробки, если ты явно не укажешь обратное.

Kroz ★★★★★
() автор топика
Ответ на: комментарий от aureliano15

О таком использовании я не подумал

Нет. Эта задача изначально решена без неймспейсов. По классике примерно так:

Все эти классы — наследники одного, где внутри них спрятаны разные реализации. После создании нужного экземпляра уже не важно, какого класса этот экземпляр, т.к. ты работаешь с ним как с базовым.

Зачем тут неймспейсы? Ну только чтобы имена не конфликтовали. Но мы можем взять префиксы, как говорили выше: «myAppDbMySqlConnection» и «myAppDbPostgressConnection». Кстати, имена даже короче, чем если неймспейсы использовать (разделителя нет). И «сократить» юзингом уже не получится, что в любом месте сразу по имени уже видно что это и откуда.

И это: НЕТ, Я НЕ ТОПЛЮ ПРОТИВ НЕЙМСПЕЙСОВ!!! ))

deep-purple ★★★★★
()
Ответ на: комментарий от deep-purple

Все эти классы — наследники одного, где внутри них спрятаны разные реализации. После создании нужного экземпляра уже не важно, какого класса этот экземпляр, т.к. ты работаешь с ним как с базовым.

А еще можно тупо подключать разные файлы с разными реализациями. Я так делаю для дебагинга - в деве подключен реальный класс для дебага, а на продакшене класс с методами-заглушками.

И если подумать наверно можно предложить еще какие-то методы для реализации подобных задач, но это не значит что другие не имеют прав на существование.

Suntechnic ★★★★★
()

Нежно и уважительно

record ★★★★★
()
Ответ на: комментарий от Kroz

лучше обходиться без неймспейсов. Раньше как-то обходились, и ничего, постоянных конфликтов имён не возникало.

удобно, когда на каждый импортируемый файл создается свой namespace. Сразу понятно из какого модуля какая функция дергается, сразу решается проблема дубликации имен, и названия функций можно делать максимально простыми.

Вот сейчас подумал и, пожалуй, соглашусь. Во многих известных си-библиотеках по сути используются неявные неймспейсы, о которых говорил deep-purple. Например, все функции библиотеки libcurl начинаются с префикса curl_, libpcap — с префикса pcap_, opengl — с gl, gtk — с gtk_ или с g_, в Qt (это, правда, уже кресты) имена классов начинаются с Q и т. д.

Если бы в си были namespaces, можно было бы вместо префиксов использовать их и сократить запись при условии использования библиотек с не совпадающими названиями функций и др. идентификаторов (хоть Suntechnic и рекомендует никогда такого не делать). Единственно, разрабам библиотек пришлось бы следить за тем, чтоб их названия не совпадали с названиями из стандартной библиотеки и системных api.

Однако оборачивать в namespace стандартную библиотеку шаблонов — имхо, перебор.

aureliano15 ★★
()
Ответ на: комментарий от deep-purple

Эта задача изначально решена без неймспейсов. По классике примерно так:

Все эти классы — наследники одного, где внутри них спрятаны разные реализации. После создании нужного экземпляра уже не важно, какого класса этот экземпляр, т.к. ты работаешь с ним как с базовым.

Такая реализация универсальнее, но и сложнее. Например, если мне надо написать клиент для работы с какой-то одной СУБД, но я пока точно не знаю, с какой, то я мог бы взять готовую библиотеку для работы с имеющейся СУБД (например, с postgres), и создать вокруг её функций простые универсальные обёртки типа connect, query, close и т. д. Если в будущем в качестве СУБД будет выбрана Oracle, то мне нужно будет всего лишь написать точно такие же обёртки для неё и изменить всего одну строчку, а именно using namespace. То же самое можно, конечно, сделать и без неймспейсов, просто подставляя в проект другие файлы и удаляя из него прежние, но если в каком-то месте мне надо будет обратиться к обеим СУБД, я получу конфликт имён.

С библиотекой классов же всё это делается намного сложнее: надо продумать иерархию, добавить виртуальные функции, конструкторы с деструкторами и т. д. и т. п. Для универсальной библиотеки или для программы, которая будет одновременно работать с любыми СУБД, это оправдывает себя. Но для описанного мною случая использование неймспейсов, имхо, рациональнее.

aureliano15 ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.