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

Язык 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

В таблицу глобального окружения. Это не всегда, но в подавляющем большинстве, _G. В самом конце.

  • Спасибо 1

Добрый день. Возможно ли узнать последнюю букву из:

local one = zero

 

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

Меня интересует - куда Луа определяет переменную, которую инициализируют, например, так:

Я могу ответить на этот вопрос. Ни в каком глобальном пространстве, а тем более в _G эта переменная не объявится (при штатной работе). Окружением этой переменной является функция mmm, и далее нее эта переменная будет недоступна, но тем не менее это глобальная переменная, а это бОльшая нагрузка на луа, что крайне не рекомендуется использовать авторами языка. Все, что может быть локальным, должно быть локальным. Если хотите изменить окружение этой переменной, то надо прибегать к действительно корректному коду, и не использовать здесь ни getfenv, ни setfenv.

 

@Kober(BRUC), я предположил, что строка может быть заготовкой для конкатенации с чем-то иным, либо оканчиваться знаком препинания, поэтому привожу свой метод:

function get_lit(str)
return str:match('(%a)[%s%p]*$')
end
str = 'Hello!'
print(get_lit(str))
str = '"Svoboda": '
print(get_lit(str))
str = 'some TEXT'
print(get_lit(str))

Если все-же исследуемая строка предполагается только вида "some text", то достаточно будет вот такого патерна: '(%a)$'.

Ни в каком глобальном пространстве, а тем более в _G эта переменная не объявится (при штатной работе).

Пруфы в студию.

Окружением этой переменной является функция mmm, и далее нее эта переменная будет недоступна

Недоступна это как? У меня все доступно, сам проверь.

function mmm()
  var = 123
end
mmm()
print(var)

@Desertir, эта переменная инициализируется в функции, а не в модуле, в сталкере же при инициализации модуля его поля не инициализируются, поэтому при инициализации этого модуля функция mmm не инициализируется, и отсюда var будет nil. Я понял слово инициализация в вопросе, как инициализация модуля, а не функции. Если же имелась ввиду инициализация переменной через инициализацию функции, то в таком случае переменной var установиться окружение текущего модуля (он в приоритете) или _G (при штатной работе, именно поэтому я упомянул возможность изменения окружения отдельным полям модуля). Иными словами, без инициализации поля модуля (с) этой переменной ее не будет существовать ни в _G ни в каком-либо другом глобальном пространстве.

Проверь сам:

function mmm()
var = 123
end
function test()
log('var = %s:<1>', _G[script_name()].var) --// инициализирован модуль
mmm()
log('var = (%s|%s):<2>', _G[script_name()].var, _G.var) --// инициализирована функция (в текущем случае и переменная)
end
В коде я постарался наглядно показать когда инициализируется переменная, а также окружение, которое ей задается при штатной работе.

 

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

 

Прочти 14 главу.

https://www.lua.org/pil/14.html

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

@Карлан, ну если так ответ поставить...

Во первых сталкер в этой теме ни при чем, тут общие вопросы. Во вторых лучше ты прочти что значит инициализация и объявление переменных. Тогда сразу станет понятно, что функция mmm вызывается (когда то и где то), а не просто болтается в модуле. Я уверен на 95%, что автор вопроса это опускает из за явности этого факта. У тебя похоже сработали остальные пять процентов.

инициализация переменной через инициализацию функции

Инициализировали, инициализировали, да не вынициализировали.

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

Окей, тогда я могу сказать, что и в сталкере и в Lua при (пере)подключении модуля (например два варианта: чистый реквайринг (для Lua) и обращение через _G (для сталкера)) его поля (функции разумеется) не инициализируются. Сталкер я упомянул лишь для справки, так как форум все таки тематический, и логично предположить, что некоторые вопрошающие все-таки требуют подсказок применительно к Lua игры :).

 

Во вторых лучше ты прочти что значит инициализация и объявление переменных. Тогда сразу станет понятно, что функция mmm вызывается (когда то и где то), а не просто болтается в модуле.

Все-таки лучше ты перечитай, такого там нет. А реальное положение вещей как-раз в тех, по твоему, 5%. Или тебе все-таки привести реальный пример из оригинальных скриптов сталкера, когда не то что функции, а целые модули просто болтаются? :)

 

Какие-то странные претензии, где я не прав применительно к штатному Lua? Если ошибок нет, зачем упоминать про сталкер, когда в данном контексте ясно, что логика работы совпадает. К тому же совершенно не ясно почему функция должна где-то и когда-то вызываться, это не есть хорошо, но это совершенно не обязательное условие. Простой пример - шаблонные функции заготовленные заранее.

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

Добавил в скрипте глобальную переменную:

FILTERS_PLACE=0

 

Далее в одной из функций записываю в нее результат рандома:

 

FILTERS_PLACE=math.random(2)
printf("FILTERS_PLACE= %s",FILTERS_PLACE) --чтобы сразу посмотреть в игре
 
Значение переменной меняется, все норм. Но почему то в этом ветвлении всегда выполняется второй вариант:

if xr_conditions.actor_in_zone(actor, npc, {"jup_b8_heli_4"})
		then
		if FILTERS_PLACE==1 then
			db.actor:give_info_portion("soulsDiedArmorsHeliJupiterDone")
			alife():create("dust_filter", db.actor:position(), db.actor:level_vertex_id(), db.actor:game_vertex_id(), db.actor:id())
			alife():create("dust_filter", db.actor:position(), db.actor:level_vertex_id(), db.actor:game_vertex_id(), db.actor:id())
		else
			db.actor:give_info_portion("soulsDiedArmorsHeliJupiterDone")
			news_manager.send_tip(db.actor, "no_filters", nil, "seeker", nil, nil)
		end
		
	end

 

 

 

Есть идеи, почему это происходит?

@KitkaT.Net, товарищ naxac писал недавно: Перед FILTERS_PLACE=math.random(2) напиши math.randomseed(os.time())
math.randomseed(os.time())

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

 

upd: да, это не помогло)) У меня другая проблема. Если я не меняю значение своей глобальной переменной - то "==" срабатывает, если рандомлю ее (и ее значение после рандома я смотрю в логе), то нет.

 

updupd: я понимаю что это звучит бредово, поэтому и решил здесь спросить. Может быть есть какие-нить особенности языка, которые я не знаю.

Изменено пользователем KitkaT.Net

При вызове random(2) не может - только целое число.

@KitkaT.Net, рекомендую в вышеупомянутое ветвление добавить ещё одну ветку вида «elseif FILTERS_PLACE==2 then ...» и перенести туда то, что сейчас находится в ветке «else». А в else для проверки сделать вместо этого вывод в лог. Если выполнение зайдёт именно туда - скорее всего, значение переменной равно начальному нулю, и присвоение случайного числа просто напросто не запускается из-за специфики скрипта.

Не оно?

action1 = function() print(1) end
action2 = function() print(2) end
local t = {action1, action2}
print(t[math.random(#t)]())

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

 

 

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

Это какая-то ерунда. Приведи свой код.

 

 


--глобальная переменная для того чтобы фильтры заспавнились только в одном вертолете
FILTERS_PLACE=nil

function souls_died_armors_give_quest() 
    task_manager.get_task_manager():give_task("souls_died_armors_task")
	task_manager.get_task_manager():give_task("souls_died_armors_task_jup")
	task_manager.get_task_manager():give_task("souls_died_armors_task_zat")
	--task_manager.get_task_manager():give_task("souls_died_armors_task_zat2")	--так как нельзя залезть на плато
	task_manager.get_task_manager():give_task("souls_died_armors_task_zat3")
	
	math.randomseed(os.time()) 
	FILTERS_PLACE=math.random(3)
	
	printf("FILTERS_PLACE= %s",FILTERS_PLACE)
	--news_manager.send_tip(db.actor, FILTERS_PLACE, nil, "seeker", nil, nil)
end

function searchingHeliJupiter(actor, npc)
	if xr_conditions.actor_in_zone(actor, npc, {"jup_b8_heli_4"})
		then
		printf("FILTERS_PLACE= %s", FILTERS_PLACE)
		if FILTERS_PLACE==1 then
			db.actor:give_info_portion("soulsDiedArmorsHeliJupiterDone")
			db.actor:give_info_portion("soulsDiedArmorsHeliFounded")
			alife():create("dust_filter", db.actor:position(), db.actor:level_vertex_id(), db.actor:game_vertex_id(), db.actor:id())
			alife():create("dust_filter", db.actor:position(), db.actor:level_vertex_id(), db.actor:game_vertex_id(), db.actor:id())
		else
			db.actor:give_info_portion("soulsDiedArmorsHeliJupiterDone")
			news_manager.send_tip(db.actor, "no_filters2", nil, "seeker", nil, nil)
		end
		
	end
end

 

 

Изменено пользователем KitkaT.Net

@KitkaT.Net,

Делаю тест. В модуле test.script пишу такой сокращённый код:

FILTERS_PLACE=nil

function souls_died_armors_give_quest()
    FILTERS_PLACE = 1
end

function searchingHeliJupiter()
    printf("FILTERS_PLACE= %s", FILTERS_PLACE)
end

Затем выполняю обе функции:

test.souls_died_armors_give_quest()
test.searchingHeliJupiter()

 

В логе печатается "1", т.е. переменная прекрасно меняется. Только она не глобальная, а в модуле test.script.

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

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

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

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

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

Войти

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

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

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