Я бы просто создал массив массивов, где индекс равен значению i.
Нет никакого «правильного» способа сделать это, так как Lua действительно не отличает код от того, откуда он пришел, это все просто функции. Тем не менее, это, по-видимому, работает в Lua 5.1:
matthew @ silver: ~ $ cat hybrid.lua, если pcall (getfenv, 4), затем печатает («Библиотека») еще печатать ( «Основной файл») end matthew @ silver: ~ $ lua hybrid.lua Основной файл matthew @ silver: ~ $ lua -lhybrid Библиотека Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio & gt; ^ C matthew @ silver: ~ $ lua Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio & gt; требуют «гибридной» библиотеки & gt; ^ C matthew @ silver: ~ $
Он работает, проверяя, превышает ли глубина стека 3 (нормальная глубина для файла в интерпретаторе Lua на складе).
Я также включу эту (немного более портативную) альтернативу, хотя она делает еще больший скачок в эвристике, и даже в любых встроенных / настраиваемых конструкциях Lua. имеет случай сбоя (см. ниже):
matthew @ silver: ~ $ cat hybrid2.lua function is_main (_arg, ...) local n_arg = _arg и #_arg или 0; если n_arg == select ("#", ...), то для i = 1, n_arg do, если _arg [i] ~ = select (i, ...), тогда print (_arg [i], "не соответствует" , (select (i, ...))) return false; end end return true; end return false; end if is_main (arg, ...), затем print («Основной файл»); else print («Библиотека»); end matthew @ silver: ~ $ lua hybrid2.lua Основной файл matthew @ silver: ~ $ lua -lhybrid2 Библиотека Lua 5.1.4 Авторское право (C) 1994-2008 Lua.org, PUC-Rio & gt; ^ C matthew @ silver: ~ $ lua Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio & gt; требуется библиотека «hybrid2» & gt;
Это работает, сравнивая содержимое _G.arg с содержимым «...». В основной части они всегда будут одинаковыми. В модуле _G.arg по-прежнему будут содержать аргументы командной строки, но «...» будет содержать имя модуля, переданное require (). Я подозреваю, что это ближе к лучшему решению для вас, учитывая, что вы знаете свое имя модуля. Ошибка в этом коде заключается в том, что пользователь выполняет основной скрипт с 1 аргументом, и это точное имя вашего модуля:
matthew @ silver: ~ $ lua -i hybrid2.lua hybrid2 Lua 5.1.4 Авторское право (C) 1994-2008 Lua.org, PUC-Rio Основной файл & gt; требуется «hybrid2» Main file & gt;
Учитывая вышеизложенное, я надеюсь, что вы знаете, где вы стоите, даже если это не совсем то, что вы имели в виду:)
Обновление: для версии of hybrid.lua, который работает в Lua 5.1 и 5.2, вы можете заменить getfenv на debug.getlocal:
, если pcall (debug.getlocal, 4, 1), затем напечатайте («Библиотека») еще print («Основной файл») end
, если arg ~ = nil и arg [0] == string.sub (debug.getinfo (1, 'S'). source, 2) затем распечатайте «Основной файл», затем распечатайте «Library» end [ ! d1]
Объяснение:
arg
, с arg [0]
- имя скрипта. debug.getinfo
возвращает таблицу информации, описывающую функцию на уровне стека, заданную его аргументом с номером ( 1 относится к функции, вызывающей getinfo
; 0 относится к getinfo
). Его второй параметр не является обязательным: он определяет, какое подмножество полей getinfo извлекается. [!d]] source
таблицы, возвращаемое getinfo
для файлов, содержит строку S . имя файла, в котором была определена функция, с префиксом @
. Передав значение этого поля в string.sub (..., 2)
, мы разделим его на @
. (Поле short_src
содержит имя без @
, но это потому, что оно определено как «удобное для печати» имя и менее безопасно, чем удаление источника [ ! d14].)
Обратите внимание, что этот код использует функцию debug
, поэтому в 5.2 вам нужно будет потребовать отладки
до быть в состоянии использовать его.
arg
определяется как глобальная переменная и содержит точно имя модуля, вы будете думать, что модуль вызывается как основной файл.
– coldfix
11 September 2013 в 18:26
Возможно, вы можете иметь дело с библиотекой отладки с функцией debug.getinfo ()
, если debug.getinfo (1) .what == "main" then - Main execution end
Для получения дополнительной информации см. справочное руководство.
Что случилось с этим:
$ cat aa.lua #! / usr / bin / lua if (arg ~ = nil и arg [-1] ~ = nil), затем напечатать " main "else print" library "end $ ./aa.lua main $ ./aa.lua arg1 arg2 main $ cat bb.lua #! / usr / bin / lua print (" in bb ") $ lua -laa bb. lua library in bb $ lua Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio & gt; требуется библиотека «aa» & gt;
arg
может быть определена как глобальная переменная в вызывающем коде. Иначе это просто и здорово!
– coldfix
11 September 2013 в 18:03
Когда Lua требует
sa module, он передает ему имя, которое было требует
d с помощью varargs ( ...
).
Итак, если ваш скрипт не намерен принимать какие-либо аргументы (из командной строки или иначе), вы можете использовать что-то вроде
, если ... затем верните this_mod - -module case else main () --main case end
Обратите внимание, однако, что это не является надежным в (полностью) возможном случае, когда вы принимаете аргументы. Однако на этот момент вы можете совместить это с ответом Лукаша, чтобы получить:
, если не package.loaded [...], тогда - главное дело else - конец кода конца
Все еще не идеально (например, если скрипт вызывается с первым аргументом строки
или именем какого-либо другого уже загруженного модуля), но, вероятно, достаточно хорош. В других ситуациях я откладываю ответ MattJ.
Я использую lua 5.3 и имею проблемы с большинством предложений здесь. Это то, что сработало для моего использования:
local my_module = {} ... если os.getenv ('CLI'), то main () else возвращает my_module end
При запуске из командной строки я просто определил переменную среды, такую как:
CLI = 1 lua my_script.lua
Работает для мне ™
вы можете попытаться проверить, требуется ли модуль.
из документации:
package.loaded Таблица, используемая требованием для управления, какие модули уже загружены , Если вам требуется модуль modname и package.loaded [modname] не является ложным, требуется просто вернуть сохраненное там значение.
blockquote>С помощью этого вы могли бы написать:
if not package.loaded ['modulename'] then main () end
arg [0]
тоже не будет работать, поскольку модули lua сопоставляются после ?. lua;?. BIN
(BIN - это расширение файла для родной библиотеки, например .so или .dll)
– user
23 December 2010 в 18:44
package.loaded
будет вставлена только после возвращения модуля.
– coldfix
11 September 2013 в 18:05
getfenv
, поскольку он кажется меньшим. я определенно буду держать в голове другое решение. – user 24 December 2010 в 06:42getfenv
не работает в lua5.2 :( – coldfix 11 September 2013 в 18:14debug.getinfo
вместоdebug.getlocal
, что делает ненужным использованиеpcall
. С уважением, Томас – coldfix 11 September 2013 в 21:27