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

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


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

С чего начинать и где взять.

 

Установка Lua:
http://www.amk-team.ru/forum/index.php?showtopic=11584&p=629106

 

Руководство «Программирование на языке Lua», третье издание:
http://www.amk-team.ru/forum/index.php?showtopic=11584&p=905308

Изменено пользователем Kirgudu
Ссылка на комментарий

abramcumner

Спасибо за исследования.. Полезная информация.

Но...Ни фига не понимаю в том, что не касается Lua(т.е. код С, С++), но из того что ты привёл (даже я понял принцип), действительно - вопрос закрыт.

Изменено пользователем Gun12
Ссылка на комментарий

Интересно, насколько неправильно я понимаю, что имея функцию вида function inc_a( a ) return a+1 end обращаться к ней как this.inc_a( a ) - бессмысленно чуть более, чем полностью ?

Ссылка на комментарий

Dennis_Chikin,

не совсем понятно, о чём именно вопрос. Именно к такой функции бессмысленно? Или используя this? this - это ссылка на текущий модуль. Не до конца уверен, чей именно это сервис - внутренний игры или luabind, но точно не чистого Lua. Насчёт того, работает ли. У меня работает, я это даже использовал в своей реализации сохраняемых таймеров для отвязки от необходимости явно указывать имя модуля, в котором расположен код таймера.

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Ссылка на комментарий

:не совсем понятно, о чём именно вопрос. Именно к такой функции бессмысленно?

Да, именно  такой. Или реальный пример:dialogs.script:

 

function is_wounded(first_speaker, second_speaker)
    if db.storage[first_speaker:id()].wounded ~= nil and
       db.storage[first_speaker:id()].wounded.wound_manager.can_use_medkit == true
    then
        return false
    end

    return xr_wounded.is_wounded(first_speaker)
end

function is_not_wounded(first_speaker, second_speaker)
    return not this.is_wounded(first_speaker, second_speaker)
end

 

 

 

На правильное использование похоже вотэто: class "motivator_binder" ( object_binder ) ...

:bind_object(this.motivator_binder(npc))

 

 

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

В смысле ? global name space ? функция в одном модуле, зовем из другого ? Изменено пользователем Dennis_Chikin
Ссылка на комментарий

Dennis_Chikin,

Именно к такой функции не бессмысленно.

 

В отличии от модулей lua, в Сталкере, для функций каждого из файлов(т.е. модулей), окружением устанавливается не данный модуль, а глобальное окружение (_G) !

При вызове функций (использовании не локальных переменных), их поиск будет происходить в таблице _G.

 

Поэтому, если вызвать функцию из примера просто как is_wounded(...), то эта функция будет и запрашиваться из таблицы _G.

Там такой нет. Вылет.

 

Функции с такими названиями есть в нескольких файлах (модулях). Напр. в xr_conditions, xr_wounded ну и в dialogs.

Вот, как известно, и вызывается как имя_модуля.имя_функции : xr_wounded.is_wounded , dialogs.is_wounded ...

Имена то загруженных модулей в _G есть.

 

Также для каждого модуля устанавливается поле с именем - this (типа в lua) и значением - сам модуль (таблица, юзердата не важно)

Теперь, если функция из модуля, должна вызвать другую функцию из этого же модуля, то нужно писать(из указанного примера) dialogs.is_wounded(...).

Но поскольку есть переменная this  (синоним dialogs), то можно писать и this.is_wounded(...) что одно и то же в рамках одного модуля.

Ссылка на комментарий

Поэтому, если вызвать функцию из примера просто как is_wounded(...), то эта функция будет и запрашиваться из таблицы _G.

 

Там такой нет. Вылет.

 

Я видимо что-то не понимаю. Сперва поиск функции будет осуществляться в текущем модуле (_M), там она есть. От куда вылет?

Ссылка на комментарий

Доброго времени суток.

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

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

Ну, и собственно вопрос: как быть? Можно ли изменить кодировку строки?

userbar368.png

Ссылка на комментарий

Callisto, функции обработки текста в Lua (да и не только) ориентированы на латиницу и не следует ожидать бОльшего, чем заложено... ;-)

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

1. Создаем табличку соответствий малых - заглавным:

tbl_LowUp = {
	["а"] = "А",
	["б"] = "Б",
	["в"] = "В",
	["г"] = "Г",
	["д"] = "Д",
	["е"] = "Е",
	["ё"] = "Ё",
	["ж"] = "Ж",
	["з"] = "З",
	["и"] = "И",
	["й"] = "Й",
	["к"] = "К",
	["л"] = "Л",
	["м"] = "М",
	["н"] = "Н",
	["о"] = "О",
	["п"] = "П",
	["р"] = "Р",
	["с"] = "С",
	["т"] = "Т",
	["у"] = "У",
	["ф"] = "Ф",
	["х"] = "Х",
	["ц"] = "Ц",
	["ч"] = "Ч",
	["ш"] = "Ш",
	["щ"] = "Щ",
	["ъ"] = "Ъ",
	["ы"] = "Ы",
	["ь"] = "ь",
	["э"] = "Э",
	["ю"] = "Ю",
	["я"] = "Я"
}

 

2. Используем функцию для перевода 1-го символа строки в Upper:

function SpellingBeginning(text)
  local str = text and text:match('^%s*(.*)') --/ убираем начальные пробелы
  if not (str and str ~= "") then return text end --/> текст без значимых символов
  
  local first = str:sub(1,1) --/ 1-ый символ строки
  if first:match('%l') then --/ если буква в малом регистре
    str = str:upper(first)..(str:sub(2) or "") --/ меняем на заглавную
  elseif not first:match('%p') then --/ если не латиница...(кириллица!)
    for low,up in pairs(tbl_LowUp) do --/ подбираем табличное соответствие
      if first == low then
        str = up..(str:sub(2) or "") --/ меняем на заглавную
        break
      end
    end
  end
  
  return str --/>
end 

 

 

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

Ссылка на комментарий

Callisto, ну это смотря с чем ты работаешь.

Для чистого lua можно сменить кодировку.

У меня (Win7 rus) сработала эта:

s = "строка"
os.setlocale("Russian_Russia.10007") -- или "Russian_Russia.10017" (Ukraine)
print(s:upper()) -- СТРОКА
Изменено пользователем Gun12
Ссылка на комментарий

Artos, о таком способе подумывала, но понадеялась, что есть какой-нибудь стандартный способ. Спасибо, теперь так и реализую.

 

Gun12, Твой вариант не сработал.

У меня тоже W7, но на сколько чистый Lua- не знаю :) Делаю скин для программы Rainmetr и штатных способов не нашла, поэтому и решила использовать скрипт. А строку получаю при парсинге страницы в интернете.

userbar368.png

Ссылка на комментарий

Gun12 (и Callisto), данный способ со сменой локализации проходит только в двух случаях - или в систему ставится Lua-компилятор, а приложение использует или в само приложение портируется. Учитывая, что тема все же связана я игрою - оба варианта для "Сталкера" не применимы, т.к. уже имеющийся в движке сильно усеченный компилятор не "умеет локализоваться" (это инфа для модмейкеров).

Ну а для "обычного приклада" - тут уже по ситуации. ИМХО, если программа "Rainmetr" ориентирована на обычного пользователя, то потребуется именно в само приложение встраивать Lua-компилятор с возможностью локализации(ий)... ну или делать встраиваемый в систему компилятор и "обучать" программу работать с ним. (овчинка выделки не стОит)

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

Ссылка на комментарий

Что-то я слегка не понял эту конструrцию:


if sDiv then sPattern = '[^%s%'..sDiv..']+'

..

for sValue in sStr:gmatch(sPattern) do table.insert(tRet, sValue) end

Если sDiv есть, то ЧТО у нас будет в таблице ?
Ссылка на комментарий

Если есть некая строка "sDiv", то шаблон "sPattern" будет иметь вид - '[^%s%'..sDiv..']+'

(иначе, наверное, другой ?)

 

В строке "sStr" будет происходить поиск всех вхождений шаблона "sPattern"

Каждое найденное вхождение такого шаблона записывается в переменную "sValue" и заноситься в таблицу "tRet".

 

Думаю что объяснение не очень. Но и вопрос не лучше. Полнее пожалуйста. Что именно не ясно?

Изменено пользователем Gun12
Ссылка на комментарий

Смысл сего действа неясен. То есть, при sDiv == "," и строке ",,,,,,,,,," - получаем таблицу с 10 запятыми ? А из строки 12345,6789 получим таблицу с "12345," и "6789" ?

Да, иначе там else pattern = "[_%w]+" - это как раз понятно.

 

 

И вот еще тоже из той же серии. Здесь у меня вообще фантазия отказывает:

for k, v in string_gfind( s, "(.*)" ) do t[k] = v end

А это что должно делать ?

Изменено пользователем Dennis_Chikin
Ссылка на комментарий

Ага. Понятно что тебе не понятно :)

 

Действительно, в приведённом тобою примере смысла меньше, чем мало.

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

local tRet = {}
local sStr = "ab Ab aB AB"

sPattern = '%l%S+' -- {'ab','aB'}
sPattern = '%u%S+' -- {'Ab','AB'}

for sValue in sStr:gmatch(sPattern) do
   table.insert(tRet, sValue)
end
Изменено пользователем Gun12
Ссылка на комментарий

 

for k, v in string.gfind( s, "(.*)" ) do t[k] = v end

По-моему, это лишено смысла. Если надо получить два значения из string.gfind, то в паттерне надо указать две группы, т.е. пары скобок. Здесь же имеем одну, так что v всегда будет nil. К тому же сам шаблон внутри группы ".*" по сути означает "последовательность любых символов любой длины", так что этот цикл всегда делает одну итерацию, при первой и единственной итерации возвращая в k всю строку.

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Ссылка на комментарий

На самом деле в этом примере итерации будет две.

Вроде и знаю что две, но понять почему - не могу.

Где-то тут зарыто :

local s = 'abc'
print(s:match('^()a()b()c()$')) -- 1 2 3 4

При "gmatch"-е  с шаблоном ".-" находятся места символов (не сами символы) - 4 шт.

При "gmatch"-е  с шаблоном ".*" находится вся строка до нуль-символа. Вот тут думаю, что эта строка находится до последнего шаблона пустых скобок перед нуль-символом.

А при следующей итерации определяется и сам нуль-символ (почему-то ???). Не пойму, короче.

Изменено пользователем Gun12
Ссылка на комментарий

Dennis_Chikin, задавая подобные вопросы стОит приводить не выдранные куски вода, а все взаимосвязанные...

Предполагаю, что приведенное в #792 имеет отношение к этой функции: 

--/ Разделяем строку 'sStr'
--/ опционально: [sDiv=='string'] - разделитель (при 'nil': по словам)
--/ опционально: [Mode==...] - тип таблицы на выходе (nil:List|true:ToTrue|false:ToNum)
function fSplitStrToTbl(sStr, sDiv, Mode, bNoErrLog)
  local tRet = {}
  local sPattern,sValue = "",""
  if sDiv and type(sDiv) == 'string' then --/ если divider задан: разделяем по нему
    sPattern = '%s*([^'..sDiv..']+)%s*' --/'[^%s%'..sDiv..']+'
  else --/ разделяем слова
    sPattern = '[%w%_]+'
  end
  if Mode == nil then --/ обычный массив
    for sValue in sStr:gmatch(sPattern) do
      table.insert(tRet, sValue)
    end
  elseif Mode == true then --/ таблица '[значение]=true'
    for sValue in sStr:gmatch(sPattern) do
      tRet[sValue] = true
    end
  elseif Mode == false then --/ таблица '[idx] = число или стринг'
    local iIdx = 1
    for sValue in sStr:gmatch(sPattern) do
      tRet[iIdx] = tonumber(sValue) or sValue
      iIdx = iIdx +1
    end
  end
  return tRet --/>
end

 

Как видно патерн, вызвавший у тебя вопрос, закоментирован(!) а рабочим является: 

sPattern = '%s*([^'..sDiv..']+)%s*'

Т.о. исходная строка (sStr) будет разделяться по патерну, а не "из строки выделяться патерны", и в таблицу будут заноситься именно куски строк разделенные патерном, а не "Каждое найденное вхождение такого шаблона записывается в переменную "sValue" и заноситься в таблицу".

Причем, в зависимости от еще одного параметра(Mode), в таблицу куски строк будут заноситься различными способами... 

Второй пример (с "(.*)") действительно, лишен практического смысла, о чем уже сказано выше.

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

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

Ссылка на комментарий

Artos, буду буквоедствовать.

Если бы я сказал : "Каждое найденное вхождение такой строки..."

Но было сказано именно "шаблона", который, как известно, хоть и является строкой, но есть набором специальных элементов со всеми вытекающими.

 

Кстати, а зачем объявлять локальную sValue='' в строке  local sPattern,sValue = "","" ?

Она и так локальна для цикла for.

Изменено пользователем Gun12
Ссылка на комментарий

Artos, приведенное - это amk ?

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

Очевидно, он был кем-то раскомментирован. Или взят откуда-то еще до того, как был закомменчен.

Ссылка на комментарий

Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

Создать аккаунт

Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!

Зарегистрировать новый аккаунт

Войти

Есть аккаунт? Войти.

Войти
  • Недавно просматривали   0 пользователей

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