Перейти к контенту

Язык Lua. Общие вопросы программирования


Malandrinus

Рекомендуемые сообщения

Dennis_Chikin

Чтобы как то закругляться:

Создавая таблицу и используя не: for i=1, NN do table.insert( t, i ) end , а for i = 1, NN do t = i end - мы в цикле(!) получаем целостную таблицу подчиняющуюся всем правилам для индексированной таблицы.

Oднако(!), стОит только добавить еще одно значение таким методом: t[NN+1] = NN+1 - то тут же любое обращение к такой таблице показывает, общий об'ем вроде как NN+1, но(!) при использовании table.remove( t, NN+1 ) - удаляется не NN+1, а именно NN, т.е. тот (последний) индекс, который был в изначальной индексированной части.

Т.е. именно для игры резюме таково: любое добавление (не в цикле) в конец таблицы (или за него) методом t[#t+1] = val - разбивает таблицу на две части разного типа и применение table.remove допустимо только к индексированной части таблицы.

Если ты будешь использовать методы только table.remove/insert - то никаких коллизий с таблицей не происходит.

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Поделиться этим сообщением


Ссылка на сообщение
Callisto, если структура таблиц не позволяет их менять (что имеет место быть в предложенном варианте от Gun12) то:

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Поделиться этим сообщением


Ссылка на сообщение

Gun12, к сожалению в исходном вопросе нет условий по выбору структуры таблиц и порою приходится подстраиваться/использовать "как есть". Конечно же вариант предложенный тобою более оптимален, но если таблицы именно как в примерах вопроса - то это уже или неочевидно или даже неприменимо.

 

Примечание: Т.к. это все же топик в разделе "Школа ...", то упоминание о различных вариантах вполне уместно. ИМХО. Ну а выбор варианта - это уже и по контексту и по вкусу. ;-)

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Поделиться этим сообщением


Ссылка на сообщение

Callisto, ну вот тепеть более понятны условия задачи/вопроса, в отличии от первоначальной формулировки:

Имеется три таблицы
, которая обычно трактуется как: "Дано: ... , требуется ..."

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

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

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Поделиться этим сообщением


Ссылка на сообщение

Struck, чем тебе мануалы по Lua не угодили, что читаешь нечто в C языках?

Все расписано по полочкам, хотя конечно же языком тех, кто все же в общей теме.

Уж если тебе непонятно "найденное вхождение", то без технического переводчика (т.е. на язык чайников в технических текстах) тебе будет не просто ... ;-)

"найденное вхождение" - упрощенно: содержит ли строка искомый символ и соответственно сам символ и место в строке, где этот символ найден.

Твой патерн вероятно означает (хотя зависит от метода к которому применяется):

Требуется вернуть от конца строки 1 и не более символ не равный пробелу. Т.е. если в конце строки имеется один символ после и/или пробела(ов) или даже без пробелов - он и будет "найден".

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Поделиться этим сообщением


Ссылка на сообщение

Мда-а-а, вопросы ты тоже задавать пока не научился. Как ты думаешь, будет ли кто-то отвечать на подобное: "Я вот тут, не зная буковок, написчал чАвото, не подскажете каков смысл мною написанного?" :crazy:

1. Задавать вопрос нужно по сути, т.е. указывать цель, а не давать кусок своего, зачастую неверного, предположения/решения и прося раз'яснить то, чего порою и невозможно раз'яснить.

2. Раз нашел мануал - почитай его не бегло! Все там найдешь.

3. "Волшебные символы" порой имееют не одно значение, которые зависят и от контекста и от места ... Символ '^' может означать и "с начала строки" и "не", т.е. указываемые в маске символу НЕ должне встречаться, ну и т.п.

4. "Твой" код - опять кастрирован, и как минимум должен иметь начало, типа: my_string = string.gsub(str, "^%s*(.-)%s*$", "%1"), т.е. идет итерация по заданной строке (str) и результат замены возвращается в my_string.

 

Добавлено через 4 мин.:

Кактус_523

один и более любой символ пишут так: '.+'

%s* - означает ни одного или более (чем один), т.е. пробелов может и не быть вовсе.

 

и согласен, патерн, да еще для gsub, бредовый. ;-)

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Поделиться этим сообщением


Ссылка на сообщение

Struck, флудить мы все горазды, а вот по сути спрашивать иль отвечать - сей факт становится все реже и реже ... ;-(

 

1. Если тебе захотелось разобраться, то почему ты считаешь, что предварительное чтение материалов по теме - не обязательно, и можно напрямую просить растолковать то, что расписано специально для тех, кто хочет разобраться?

2. Твоей функции уже пять лет как исполнилолось и взята она (trim) из AMK-мода. Провда тот кто тебе ее дал заодно и тамошнюю функцию explode привел скорее также к бредовой форме, чем к улучшению.

 

Бредовость патерна именно для gsub в том, что этот метод по определению обрабатывет строку от начала и до конца (читаем мануал!), т.о. бессмысленно задавать символы "от начала" и "до конца".

Уже давно имеется на форумах (и этом тоже) и в модах нормальная замена:

function trim(str)
  if str and str ~= '' then
    return str:match('^%s*(.*%S)') or '' --/>
  end
  return '' --/>
end

Возврат пустой строки избавляет от фатальных ошибок в случае, если строка содержит одни пробелы, что "дорабатанная" explode пропустит на ура, т.к. при наличии только пробелов условие #str == 0 как раз не отсекает подобные строки ... Отсекать нужно именно пустые строки или имеющие только пробелы, ну да это уже по-контексту стоящей задачи делается.

 

Ну а "бредовость" в нынешнем виде функции explode в том, что достаточно бессмысленная связка условий:

if #sep == 0 or #str == 0 then return end

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

Ну и нашпигование внутри функцией string.find (которая уже по выходу игры устарела в Lua) в цикле - вызывает улыбку и недоумение.

 

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

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Поделиться этим сообщением


Ссылка на сообщение

Дам все же иную трактовку нашим ответам и принесу извинения команде АМК, написавшим исходную связку функций, которую кто-как курочит и корежит:

Исходная связка trim + explode задумывалась достаточно многофункциональной и имела на входе помино собственно разделяемой строки и разделителя (обычно по-запятой ',') еще и флаг clear, т.е. чистить от пробелов или нет.

К сожалению, тяга к упрощениям в названиях и трактовках превратила trim в синоним "чистка от пробелов".

Однако, назначение вышеупомянутого патерна и результат на выходе - очистка от начальных и конечных пробелов, т.е. очистка строки/линии, а не слова. Вот тут как раз и играют важную роль '^' и '$' уточняющие, что следует чистить ТОЛЬКО от начала и от конца.

 

Все привыкли, что в задаваемой строке для разделения идет типа: ab, cd, ef, ...

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

в том же АМК-моде (например, в интерактивных.новостях) для разделения использовались строки типа: a b, c d e, f g, ...

т.е. требовалось делить именно только по разделителю и убирать начальные и завершающие пробелы, оставляя связки слов (темный сталкер, зеленый новичек, ...) именно неоазделенными.

Исходная trim как раз выполняла задачу как trim_line, а не как trim_word, хотя на порядок проигрывает в производительности указанному выше эквиваленту.

А вообще, без указания задачи для чего служит патерн, довольно глупо спрашивать/критиковать иль предлагать, вариаций немало:

string.trim(str) -- обрезка строки (line)

string.trim_l(str) -- обрезка строки слева (left)

string.trim_r(str) -- обрезка строки справа (right)

string.trim_w(str) -- обрезка строки по первому слову (word)

...

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Поделиться этим сообщением


Ссылка на сообщение

Vano_Santuri, штатных "шифровальщиков" в Lua не предусмотрено ...

 

Да и стОит ли заморачиваться, тратить времяя и воззвращаться к временам 5-ти летней давности, когда подобное пытались применить и в АМК-моде и др. ? Всегда найдется "не школьник" и отдаст "школоте" на растерзание любые подобные "закодированные" коды ... Да и почему игроку не давать возможности "поиздеваться" над самим собою, внося не или иные (даже глупые) правки?

 

Ну а если приспичило - смотри потребное в стареньких версиях АМК-мода ... даже в немалом кол-ве нынешних модов остался амк-рудимент от выхолощенной amk.decode©.

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Поделиться этим сообщением


Ссылка на сообщение

ColR_iT, или ты некорректно сформулировал вопрос или ... полез в дебри исходников Lua, а не в общие вопросы программирования на этом языке.

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

Или переформулируй вопрос или переходи к следующим ... тогда может будет понятна суть первого. :-)

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Поделиться этим сообщением


Ссылка на сообщение

*Shoker*, аналогов функций работы с битами в чистом Lua нет, поэтому то и портированы в игру указанные тобою функции.

Собственно названия функций сами подсказывают их функционал: 'or' - ИЛИ , 'and' = И и т.д.

В lua_help или в справочнике можно уточнить необходимые аргументы (тип и кол-во) для использования функций.

Учитывая, что в твоей задумке фигурируют три параметра, а функции принимают только по два или даже один (bit_not), то тебе просто придется использовать промежуточные резутаты, например:

local my_flag = bit_or(FS.FS_ListFiles,FS.FS_RootOnly) --/ => 9 - промежуточный результат
my_flag = bit_or(my_flag,FS_ClampExt) --/ => 13 - конечный

ну и далее по твоему контексту: file_list_open_ex("$game_saves$", my_flag, "*.sav")

 

Можно еще проще, учитывая то, что константы класса FS не изменны - сложить в уме все потребные константы (1+8+4 = 13) и написать:

file_list_open_ex("$game_saves$", 13, "*.sav") ... но это уже не "по-программистски" :crazy:

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Поделиться этим сообщением


Ссылка на сообщение

Desertir,

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

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

 

 

ColR_iT, принципиальной разницы нет, как и в скорости. Не забываем, что Lua все одно читает (парсит) построчно код и транслирует его в соответсвии с заложенными в него правилами - в итоге оба варианта идентичны.

Ну а нюансы - они всегда найдутся ... ;-) например, если в качестве index выступает аналогичный из другой таблицы, то при неудачном написании может получаться типа: tbl[tbl2[index2]] и при парсинге такой записи парсер вылетает по ошибке из-за наличия ']]' , что является одним из пары оператора комментирования. Поставив пробел ( tbl[ tbl2[index2] ] ) - "нюанс" исчезает.

Изменено пользователем Artos
  • Не нравится 1

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Поделиться этим сообщением


Ссылка на сообщение

Gun12, да, это именно в контексте со СТАЛКЕРом, и именно нюанс, а не правило.

1. Не забываем, что в СТАЛКЕРЕ сдвоенные квадратные скобки '[[' - не только оператор группового комментирования, а и некий оператор, указыващий на обработку строчного значения: [[misc\script_sound]].."ltx" == "misc\\script_sound.ltx"

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

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

Суть в словах: "Ну а нюансы - они всегда найдутся" ;-)

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Поделиться этим сообщением


Ссылка на сообщение

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

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

Мною дан ответ именно на вопрос и в частности на "или ещё какие-нибудь нюансы? ", и приведен один из них.

sapsan, Desertir вами отрицается само существование упомянутого нюанса? Нет, так на кой тратите время на нетребуемое авторами вопроса и ответа способы исправления этого частного нюанса (тем более один из ваниантов с пробелом уже дан)? :dash2: Успокойтесь, когда спросят об этом тогда и пишите трактаты, а еще лучше - отвечали бы на сами вопросы, но по сути, а не ... потугами трактовать частности.

 

Desertir, (по сути) ты хоть понимаешь о чем речь?

Автор вопроса дал две формы записи, о второй (tbl.index) ты в ответе сказал НЕВЕРНО(!) - "во втором это ключ-строка, т.е. константа". Это такая же переменная как и в первой форме записи, или до тебя до сих пор это не дошло и требует разъяснения?

И для чего расписывать частность (да еще второй раз). Никто не ставит под сомнение неидентичность двух записей при строковом значении index, или ты себя убеждаешь в очевидном?

Речь о том, что автор вопроса не случайно спрашивает именно про tbl[index] где index может быть любым типом данных, которыми оперирует Lua, что в твоем ответе ставится под сомнение.

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

 

sapsan, большое спасибо про упоминание названия "длинные скобки", а то и подзабыл и как-то не находил время освежить в памяти этот момент. :) Да и для других подобное напоминание не лишним будет.

Баг не работает. Или его доработать, или удалить и не пугать людей.

Прочти исходный вопрос и о том, что спрашивает автор... Если баг ворзможен - то об этом и говорит данный пример.

Изменено пользователем Artos
  • Не нравится 1

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Поделиться этим сообщением


Ссылка на сообщение

sapsan, где ты увидел рекомендации? Мною указан вариант, который позволил мне устранить ошибку при парсеринге написанного кода.

В чем по твоему бред при использовании вместо tbl[tbl2] => tbl[ tbl2 ], что позволяет не задумываться о способах комментирования данной записи?

По-мимо явных синтаксических ошибок существуют двузначности при написании кода, которые при парсинге строк могут вызывать ошибки/баги и мною называются - "неудачное" написание. Не нравится название (определение) - не используй.

  • Не нравится 1

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Поделиться этим сообщением


Ссылка на сообщение

Viнt@rь , невозможно. Об'являя локальную переменную: local vName... - ее имя должно быть определено сразу и оно (имя) не имеет типа данных (даже не 'nil'). - т.о. уже при объявлении самой переменной ты получишь фатальную ошибку оператора конкатенации (сцепления строк).

С глобальными переменными нечто подобное можно выполнять, используя представление их имен как this[ "vName"..i ], но ...какова цель в таких извратах? ;-)

Изменено пользователем Artos
  • Нравится 1

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Поделиться этим сообщением


Ссылка на сообщение

Ну так и формулировал бы не кастрированный вопросик, а в контексте задачи ...

Взгляни например на это (из скрипта спальника Симбиона):

function CUI_DreamManager:InitCallBacks()
 self:AddCallback("btn_quit", ui_events.BUTTON_CLICKED, self.OnBtnQuit, self)
 for i=1,5 do
   self["OnBtnAct_"..i] = function() self:OnBtnAct(i) end
   self:AddCallback("btn_"..i, ui_events.BUTTON_CLICKED, self["OnBtnAct_"..i], self)
 end
end

function CUI_DreamManager:OnBtnAct(iNum)
 --/ обработка iNum-кнопки
end

- и подобным образом вполне можно избегать десятков строк и отдельных функций по каждой кнопке... ;-)

(но это уже скорее тема для "Скриптования" а не по чистому Lua)

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Поделиться этим сообщением


Ссылка на сообщение

Gun12? я все же не стал бы жестко формулировать, т.к. вполне можно и к классам (а это 'userdata', см. пример выше) пристроиться... ;-)

Да и как то ... объявляя в своем скрипте/модуле глобальную переменную: My_Variable = nil , довольно странно обзывать ее полем таблицы, хотя конечно в конечном счете это и так. :-)

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Поделиться этим сообщением


Ссылка на сообщение

Viнt@rь, для SIMBION'a существует технологический аддон SMB-SHOC_Dbg_Tools (~20.2 кБ , запакован в xdb) где возможно аналог того, что затеял или то, что может быть полезным для твоей затеи ;-)

 

*Shoker*, этот вопрос уже обсуждался. Хочешь подобное в игре (в чистом Lua это есть) - расширяй движек до активизации name_space 'debug' и почитай про его возможности и использование. В ЧН и ЗП в _G.printf(fmt,...) остались остатки примера использования от разрабов.

 

Gun12,

поэтому если суть/смысл не меняется - вполне допускаю удобное наименование, тем более более привычное для большинства на этом форуме, (порою даже жаргонарии). :-)

 

Изменено пользователем Artos
  • Нравится 1

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Поделиться этим сообщением


Ссылка на сообщение

Кину и свои 5 копеек ;-)

Не знаю где нашли ColR_iT и Shredder в кодах игры применение table.foreach иль table.foreachi, но в оригинальных кодах их нет ни в какой версии релизов ТЧ/ЧН/ЗП и ни в каком патче ТЧ.

Если создатели Lua при обновлении версии -> 5.1 и далее посчитали нужным изъять (заменить) данные методы, то наверное не из косметических соображений.

И на вкус и цвет конечно же товарисЧей нет, но читабельность кода зависит и от того, 'знакомы' ли встречающиеся по тексту функции/методы иль это экзотика. Если основная масса скриптов в приложении постоена на использовании (i)pairs, то врядли повысится читабельность от навязывания устаревших foreach(i). Каждый язык имеет свой синтаксис и свою "читабельность", и попытки читать/писать как на другом, привычном кому-то языке - это просто напросто субъективизм.

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Поделиться этим сообщением


Ссылка на сообщение
  • Недавно просматривали   0 пользователей

    • Ни один зарегистрированный пользователь не просматривает эту страницу.
×
×
  • Создать...