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

Язык 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
Ссылка на комментарий

*Shoker*

Неявная передача возможна при вызове метода, т.е. посредством двоеточия.

При этом неявной переменной self будет соответствовать значение типа таблица или юзердата.

В чистом lua это делается просто.

В таблице _G всегда есть поля с загруженными модулями (файлами). Из этих полей можно "выдрать" название модуля. (если интересно, то могу показать)

А вот в Сталкере...лень искать. Возможно есть что-то похожее на _M. Ну там this._NAME что-ли :-)

Artos

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

Shoker

  Цитата
А в Lua случаем нету возможности неявно передать в функцию название скрипта, откуда она была вызвана?

Вопрос задан неоднозначно. Из скрипта ничего не вызывается, вызывается из функции. Поэтому непонятно, что такое "скрипт, откуда вызвана функция". Ты имеешь в виду файл, где находится функция, или имеешь в виду именно функцию, откуда вызвана текущая?

 

Если нужен файл, содержащий данную функцию, то в сталкере имеется функция script_name(), которая возвращает имя текущего файла без расширения. Если же нужно имя вызвавшей функции, то это в общем случае может быть не выполнимо, поскольку у функции может и не быть имени вообще, как например в случае, если вызов был прямо из движка, или функция была определена только своим телом без имени или вообще была скомпилена на лету с использованием loadstring. Если уж совсем надо, то нужны отладочные возможности из debug, как советовал Artos. Однако использовать отладочные возможности в неотладочных целях - порочная практика: ненадёжно, ресурсоёмко, делает код малопереносимым и малопонятным. Типичный пример индусского подхода.

  Полезный утиль (Показать)
Ссылка на комментарий

Пожалуйста, обновите ссылку на скрипты из этого поста или дайте новую.

  Оффтоп (Показать)

ТЧ 1.0004. SAP и Trans mod

github

Ссылка на комментарий
  оффтоп 2 (Показать)
Изменено пользователем 7.9

всё легко

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

Есть ли в Lua возможность пропустить шаг в цикле? Приведу пример из php

foreach ($array as $k => $v ) {
   ...
   if (...) {
    continue // код ниже не будет выполнятся для текущей пары k,v
   }
   ...
}

Надеюсь, понятно объяснил

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

Shredder, конкретного оператора нет, но это можно с имитировать.

for i=1, 3 do
   if i ~= 2 then
       print (i)
   end
end

Результат понятен - пропускается цикл со значением счётчика равному двум.

Конечно, это далеко не универсальный вариант, но он работает.

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

Да это понятно. Только как раз наличие такого оператора дало бы возможность уменьшить вложенность, как ранний return в функции. Эх, жаль конечно.

Я тут недавно наткнулся на интересный вариант итерации таблиц table.foreach(table, function(k,v) ... end). Если пользоваться таким способом, то тут ранний return решает проблему вложенности. А вот как со скоростью по сравнению с pairs (ipairs)? Есть ли какие-нибудь подводные камни?

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

Shredder

Дык, а table.foreach ничем не отличается от того же итератора pairs.

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

Абсолютно тоже самое происходит и с конструкцией вида:

for key, value pairs(table) do
-- здесь по сути тело функции, которая передавалась вторым параметром для foreach.
end

Всё также пробегаемся по всем ключам таблицы и если ничего не вернули (отсутствует оператор break), то перебирать будем всю таблицу.

P.S. А к стати table.foreach в игре осталась? Вроде как её и table.foreachi нет с какой-то версии lua.

Сейчас глянул в 5.0 ещё были, в 5.1 уже исключили из стандартного набора. В игре какая версия используется?

 

Ещё заглянул в _G в 1.0006. Там функция foreach ещё есть. Но в любом случае - не вижу смысла её использовать...

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

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

 

Дабы не разводить чат в теме пишу в твоём же посте (эх, служебное положение).

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

Но, раз тебе нравится - пожалуйста, никто собственно и не возражает...

ColR_iT

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

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

Ну если бы я был автором этого языка, то неужели написал бы на С заведомо медленную функцию?

В среднем foreach и pairs работают одинаково быстро. Остальное зависит от... платформы, процессора.. и Бог его знает чего ещё. Например у меня foreach работает на пару десятых(сотых) долей секунды быстрее (при десятимилионном цикле). Тем не менее логичнее и понятнее, для меня, использовать pairs.

Но тут уж каждому своё.

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

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

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

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

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

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

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

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

7.9

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

 

Когда мне это всё надоело, я и создал обёртку с использованием ООП для классов wxLua.

Теперь красота. Вызвал конструктор с необходимым(и) полем(и)-параметром(и), а остальные добавляются автоматом.

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

Shredder,

  Цитата
Есть ли в Lua возможность пропустить шаг в цикле?

В версии 5.2 добавили goto, который решает эту задачу. Ну а в сталкере придётся извращаться. К примеру так (не претендую на оптимальность, просто как вариант):

for i = 1,7 do (function()
   -- ...
   if i == 3 then return end
   -- ...
end)() end

Данный вариант более-менее имитирует семантику continue в том смысле, что так можно сделать проверку на выход именно внутри, в точке выхода. Присутствуют накладные расходы на вызов функции (только вызов, компиляция происходит один раз), что в зависимости от ситуации может и не быть критично.

Изменено пользователем malandrinus
  Полезный утиль (Показать)
Ссылка на комментарий

Приведу пример, что для меня значит "читабельность" кода. Фрагмент из treasure_manager.script (ТЧ)

  оригинал (pairs) (Показать)
Ссылка на комментарий

Приведу пример, в котором может быть "читабельность" кого-то не устраивает, но с точки зрения корректности и оптимальности - повыше чем приведенные выше варианты:

  код (Показать)

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

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

Как раз в приведённых мною примерах я вообще не уделил внимание корректности и оптимальности, а только показал, как с помощью table.foreach можно избавиться от вложенности. Что конкретно происходит внутри цикла - я даже не вникал. Так что по пунктам 1,2 и 3 - это к GSC :)

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

Ложка дёгтя в бочку мёда...

Попытался вычислить время работы обоих итераторов в игре (ТЧ 1.0006 + X-Ray extension), вот результаты работы:

  Эксперимент (Показать)
Изменено пользователем ColR_iT
Ссылка на комментарий

Проверил для ЗП 1.6.2 + X-Ray extension, результаты:

pairs: 0.162835 sec

foreach: 0.698536 sec

Достаточно убедительный довод, чтобы впредь не использовать foreach. Жаль конечно :(

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

Эх, будет мне наукою... Как оказалось метод start() класса profile_timer не обнуляет значение, а продолжает считать.

Вот ПРАВИЛЬНЫЕ результаты эксперимента:

  Эксперимент_2 (Показать)
Ссылка на комментарий

Когда я первый раз запускал эксперимент, то подумал об этом, и создавал три разных "счётчика", поэтому у меня результаты не изменились:

##time is 162232.109375

##time is 731144.5

##time is 566500.8125

 

PS: Результаты сильно разнятся, интересно, с чем это связано? У меня процессор Intel Core Duo T8100 2.10Ghz. А может из-за версии игры?

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

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

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

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

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

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

Войти

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

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

×
×
  • Создать...