2016-01-06 3 views
2

Привет, я хочу разделить файл Lua на два файла. Тот, который содержит мои функции и тот, который может их назвать. Я провел много исследований по этому поводу, и все ресурсы, которые я нахожу, не объясняют этот процесс очень далеко. Они, как правило, говорят, чтобы использовать:Доступ к функциям Lua в других файлах

require "subsystem.lua" 

Я положил это в верхней части нового файла Lua, который сохраняется в той же директории, и я не в состоянии получить доступ ничего.

Есть ли файл конфигурации, который мне нужно изменить? Где это?

ответ

3

требуют, чтобы модуль

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

Самый простой способ узнать, сколько мест и имен, которые он использует при поиске модуля, - это просмотреть сообщение об ошибке, возникшее после сбоя require. Например, на моем компьютере, Lua 5.1 говорит, что это:

 
C:\Users\Ross>lua 
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio 
> require "xyzzy" 
stdin:1: module 'xyzzy' not found: 
     no field package.preload['xyzzy'] 
     no file '.\xyzzy.lua' 
     no file 'C:\Program Files (x86)\Lua\5.1\lua\xyzzy.lua' 
     no file 'C:\Program Files (x86)\Lua\5.1\lua\xyzzy\init.lua' 
     no file 'C:\Program Files (x86)\Lua\5.1\xyzzy.lua' 
     no file 'C:\Program Files (x86)\Lua\5.1\xyzzy\init.lua' 
     no file 'C:\Program Files (x86)\Lua\5.1\lua\xyzzy.luac' 
     no file '.\xyzzy.dll' 
     no file '.\xyzzy51.dll' 
     no file 'C:\Program Files (x86)\Lua\5.1\xyzzy.dll' 
     no file 'C:\Program Files (x86)\Lua\5.1\xyzzy51.dll' 
     no file 'C:\Program Files (x86)\Lua\5.1\clibs\xyzzy.dll' 
     no file 'C:\Program Files (x86)\Lua\5.1\clibs\xyzzy51.dll' 
     no file 'C:\Program Files (x86)\Lua\5.1\loadall.dll' 
     no file 'C:\Program Files (x86)\Lua\5.1\clibs\loadall.dll' 
stack traceback: 
     [C]: in function 'require' 
     stdin:1: in main chunk 
     [C]: ? 
> 

Посмотрев внутренне, то первый «реальный» место выглядит для xyzzy находится в файле с именем .\xyzzy.lua. Затем он пытается найти несколько папок и имен в папке, где было найдено lua.exe. Наконец, он ищет DLL, которая может предложить его. Список папок, которые он ищет для файла .lua, управляется строковым значением в package.path. (Сопоставимый список для DLL в package.cpath.) В этом значении require заменит каждый ? на имя модуля, а затем попытается прочитать файл. Используется первая для успеха.

(история здесь немного сложнее, вы можете создать «поисковик», что require будет использовать для поиска в разных местах, и даже изменить порядок встроенные в поисковиках, но это сложная тема.)

Таким образом, просто размещение модулей в файлах Lua в текущем каталоге должно работать нормально, а настройка package.path перед вызовом require для ваших собственных модулей может охватывать большинство причуд, с которыми вы столкнетесь.

Создать модуль требует

В простейшем случае, модуль является только то, что можно хранить в package.loaded.Это то, что require будет делать с ним, как только оно будет найдено, так что несколько вызовов require будут искать только один раз и всегда возвращать одинаковое значение.

Традиционный ответ - это то, что «что-то» должно быть таблицей, обычно большей частью населенной функциями, которые можно назвать, а иногда и имеющими значения. Хорошим примером является модуль math: он предоставляет множество функций, таких как sin и cos, а также полезное значение math.pi и math.huge.

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

Так оченьминимальная файл модуля может быть столь же простым, как:

return { 
    addtwo = function(a, b) return a+b end, 
    subtwo = function(x) return x-2 end, 
} 

, которые, если сохранены как example.lua могут быть использованы, как это:

local example = require "example" 
print(example.addtwo(2,2)) -- 4 
print(example.subtwo(42)) -- 40 

Лучший модуль скелет

Sticking весь ваш код в одном объявлении таблицы не будет летать для большинства реальных случаев. Он недостаточно масштабируется, и это затрудняет четкое выражение взаимосвязи между функциями, разделяющими состояние.

-- simple modules 

-- capture the name searched for by require 
local NAME=... 

-- table for our functions 
local M = { } 

-- A typical local function that is also published in the 
-- module table. 
local function addtwo(a,b) return a+b end 
M.addtwo = addtwo 

-- Shorthand form is less typing and doesn't use a local variable 
function M.subtwo(x) return x-2 end 

return M 

Почему нет вызова функции module()?

В Lua 5.1 включена стандартная функция с именем module(), предназначенная для использования в верхней части реализации модуля. Его использование никогда не требовалось, и консенсус сформировался довольно быстро, и это было не так полезно, как хотелось бы надеяться. С тех пор он устарел.

В результате простой скелет, показанный выше, не использует его и переносится для всех версий Lua с 5.1.

+0

Благодарим вас за подробное объяснение. – OT2O

3

Что вам нужно сделать, это вернуть таблицу с полями, к которым вы хотите получить доступ, в subsystem.lua, а затем назначить и использовать поля из этой таблицы в своем основном файле. Что-то в этих строках:

-- subsystem.lua 

local function doSomething() 
    -- do something useful here 
end 

local function doMore() 
    -- do something else useful 
end 

return { doSomething = doSomething, doMore = doMore } 

-- main.lua 

local subsystem = require "subsystem" -- don't add `.lua` to your `require` call 
subsystem.doSomething() 
subsystem.doMore() 

Чтобы узнать больше, вы можете проверить Modules tutorial.

+0

Мне удалось выполнить функцию, используя этот метод. Я не смог вернуть значение. Мне пришлось поместить файл substem.lua в каталог defualt моей IDE. Как я могу указать, где искать и возвращать значение? – OT2O

+0

Удостоверьтесь, что у вас есть функция 'return my-result' в вашей функции. Если это не поможет, отправьте вопрос с подробностями того, что вы пытаетесь сделать. –

1

Возможно, вы захотите использовать dofile вместо require.

dofile принимает имена файлов, с путями.

require принимает имена модулей и использует пути поиска Lua.

+0

Мне нравится идея указать, где находится мой файл, потому что расположение модуля запуталось. Можете ли вы дать мне пример вызова функции в отдельном файле и получения возвращаемого значения? – OT2O

+0

@ OT2O, файлы, запущенные с помощью 'dofile', могут создавать глобальные функции или возвращать их в таблице, например. Локальные функции просто таковы и не могут быть замечены за пределами файла. – lhf

Смежные вопросы