Делать файл только один раз в Lua

Мне было интересно, есть ли способ сделать файл lua только один раз, и любые последующие попытки сделать этот файл lua приведут к бездействию.

Я уже думал о том, чтобы сделать что-то похожее на трюк с заголовком C++ #if/else/endif. Мне интересно, есть ли стандартный способ реализовать это.

Джеймс


person jameszhao00    schedule 02.09.2009    source источник
comment
Что вы подразумеваете под файлом lua?   -  person    schedule 02.09.2009
comment
В данный момент я использую dofile() из нескольких мест в 1 файле.   -  person jameszhao00    schedule 02.09.2009
comment
я бы всегда предпочитал require перед dofile, за исключением того, что вы явно хотите делать весь файл при каждом вызове   -  person nonchip    schedule 30.08.2013


Ответы (3)


ну, require почти так и делает.

require "file" -- runs "file.lua"
require "file" -- does not run the "file" again
person Jochen Ritzel    schedule 02.09.2009
comment
Потрясающе спасибо. Я продолжал думать, что по какой-то причине мне тоже нужно определение модуля для файлов lua. - person jameszhao00; 02.09.2009
comment
Если файл, запускаемый require, не создает таблицу модулей или ничего не возвращает, require сохраняет true в package.loaded. В противном случае он сохраняет значение, возвращенное при выполнении файла. С этим хорошо взаимодействует функция module. Все это объясняется в PiL, но онлайн-копия по этим деталям не так хороша, как печатная версия. - person RBerteig; 03.09.2009

Единственная проблема с require заключается в том, что он работает с именами модулей, а не с именами файлов. В частности, require не обрабатывает имена с путями (хотя и использует package.path и package.cpath для поиска модулей в файловой системе).

Если вы хотите обрабатывать имена с путями, вы можете написать простую оболочку для dofile следующим образом:

do
  local cache={}
  local olddofile=dofile
  function dofile(x)
    if cache[x]==nil then
      olddofile(x)
      cache[x]=true
   end 
  end
end
person lhf    schedule 03.09.2009
comment
Приведенное выше решение THC4k также работает с файлами. Если файл называется abc.lua, работает require('abc'). - person jameszhao00; 03.09.2009
comment
Да, но не в том случае, если вы делаете dofile/home/lhf/scripts/abc.lua. - person lhf; 03.09.2009
comment
на самом деле вы также можете использовать require"/path/to/file.lua" - person nonchip; 30.08.2013
comment
ок, извините, неправильно вспомнил. то, что вы можете сделать, это require "relative/path/to/file" (без .lua), потому что путь поиска по умолчанию включает ./?.lua. - person nonchip; 30.08.2013

на основе ответа lhf, но используя package, вы также можете сделать это один раз:

package.preload["something"]=dofile "/path/to/your/file.lua"

а затем используйте:

local x=require "something"

чтобы снова получить предварительно загруженный пакет. но это как-то оскорбительно...

person nonchip    schedule 30.08.2013