Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

MyDC.ru _ Разработчикам [PtokaX] _ Не работает dofile(filename) ?

Автор: dimajak 17.3.2011, 0:06

Столкнулся с тем, что из файла не загружается таблица.
Создал тестовый скрипт и тестовый файл с данными.
При старте скрипта теоретически в переменную Players должна загрузиться таблица из файла test_file.dat.
В Оп-чат выводится сообщение об успешной загрузке файла.
При подключении юзера добавляется пункт в меню (команда !f), по этой команде выводится содержимое переменной-таблицы Players.
Но этого не происходит. :(
Прикрепляю архив со скриптом и файлом с данными.

Помогите найти ошибку.

 test_file.rar ( 675 байт ) : 10
 

Автор: Kingston 17.3.2011, 1:06

Сделай глобальной таблицу:

Код
Players = {}

Автор: Ksan 17.3.2011, 1:25

Ещё добавлю...чтоб при загрузке файла в Опчат показало, сколько записей в таблице, нужно чтение числа записей организовать так:

Код
function OnStartup()
    if loadfile(filename) then
        dofile(filename)
        local n = 0
        for i in pairs(Players) do
            n = n + 1
        end
        Core.SendToOpChat("Loaded "..filename.." Всего в списке = "..n)
    end
end

Иначе у тебя будет по нулям.
И то же самое сделай в ЧатАрривал, там у тебя тоже есть вывод числа записей.
Только к чему вместе с названием файла и весь путь до него? Ты же знаешь его название, так пропиши его в этом сообщении напрямую, или переменную в начале скрипта обозначь с этим названием (без пути), например, так:
Код
local fname = "test_file.dat"
и при отправлении в Опчат пиши это слово - "fname" вместо "filename"
А то выглядит несуразно:
Цитата
[04:21:49] <_OpChat_> Loaded D:/SOFT/INTERNET/P2P/HUBS/PtokaX_0411_IndyHub/scripts/test_file.dat Всего = 2

Вывод таблицы перекрой так, чтоб весь список был в одном сообщении. Например, так:
Код
    if cmd == "!f" then
        local n = 0
        for i in pairs(Players) do
            n = n + 1
        end
        local list = "\nСписок Players. Всего в списке = "..n.."\n"
        for i,v in pairs(Players) do
            list = list.."\t"..i.."\n"
        end
        Core.SendToUser(tUser, list.."Конец списка Players")
    end

В результате получишь в Опчат это:
Цитата
[04:50:01] <_OpChat_> Loaded test_file.dat Всего в списке = 2

В чате таблица так:
Код
[04:43:03]
Список Players. Всего в списке = 2
    Волотька
    TIMON
Конец списка Players

Автор: dimajak 17.3.2011, 2:15

Экспериментально выяснил, что вместо

Код
local Players = {}
работает
Код
Players = {}
т.е. без local.
Kingston правильно сказал.
Осталось понять почему?
Ведь если я определяю в скрипте переменную без local, то она должна быть доступна в других скриптах? Нет?

Цитата(Ksan @ 17.3.2011, 1:25) *
Иначе у тебя будет по нулям.
Изначально таблица пуста, поэтому нет смысла пробегать циклом. Даже если таблица из файла не пустая, то я знаю сколько в ней элементов и есть ли в ней "пустышки", ведь я создавал этот тестовый скрипт и тестовый файл с данными специально наиболее простым, дабы исключить все другие помехи. big_smile.gif Это был не тест на сообразительность. big_smile.gif

Автор: Ksan 17.3.2011, 2:31

Ни одна переменная не вылезет к другим скриптам. Глобал - относительно пространства именно одного конкретного скрипта.
В Птоке.

Автор: dimajak 17.3.2011, 2:35

Тогда смысл в "local" в скрипте?
П.С. просто затормозило мафию на несколько дней. big_smile.gif

Автор: Andrean 17.3.2011, 7:28

http://mydc.ru/ipb.html?s=&showtopic=1508&view=findpost&p=14327

Автор: Kingston 17.3.2011, 8:43

дальше скрипта переменные и фукции никуда не выйдут и доступ к к функциям и переменным одного скрипта из другого не будет, если первый скрипт не загружен.
локальные переменные заданные в функциях не доступны другим функциям и наоборот, получается. а смысл в оптимизации http://mydc.ru/index.html?showtopic=1018&view=findpost&p=7538

Автор: Setuper 17.3.2011, 9:57

Функция dofile загружает дополнительный lua код в текущий скрипт, и этой функции доступно только глобальное окружение скрипта.
В свою очередь, если в загружаемом функцией dofile файле объявляется глобальная переменная, а в самом скрипте определена такая же переменная но локально, то локальная переменная имеет выше приоритет, чем глобальная, при этом функция dofile не имеет доступа к локальной переменной. Отсюда получаем, что dofile загружает в глобальную переменную Players, а скрипт будет брать локальную переменную Players.
Для того чтобы обратиться к глобальной переменной нужно обращаться к ней через таблицу _G.
То есть в данном случае просмотреть содержимого ГЛОБАЛЬНОЙ переменной Players возможно следующим образом:

Код
for i,v in pairs(_G.Players) do