モジュール (require)
require / pico.require
スクリプト本体(main.lua)は16KiBまでです。大きなアプリは機能ごとにファイルを分けて require で読み込めます。標準Luaの require/package とは別の、アプリのフォルダだけを見る仕組みです。
require
アプリのフォルダ(main.lua のあるフォルダ)から次の順で探して読み込みます。pico.require も同じ関数です。
<名前>.lua<名前>/init.lua
名前の . はフォルダの区切りです(require("ui.dialogs") → ui/dialogs.lua)。
-- main.lua
local util = require("util") -- util.lua
local menu = require("ui.menu") -- ui/menu.lua
print(util.double(21))
-- util.lua
local M = {}
function M.double(x) return x * 2 end
return M
- 1つのモジュールは一度だけ実行され、結果(
returnした値。無ければtrue)が覚えられます。2回目以降のrequireは同じ値を返します。 - モジュールの中からさらに
requireできます。循環(AがBを、BがAを読む)はエラーです。 - 1つのファイルは32KiBまでです(
main.luaは16KiB)。 - 名前に使えるのは英数字・
_・-と区切りの.だけです。..や/は使えません。アプリのフォルダの外(sd_outside_app_dir権限があっても)は探しません。 - 構文エラーや実行時エラーは、モジュールのファイル名と行つきでそのまま
requireの呼び出し元へ伝わります(pcall(require, ...)で受けられます)。
先読みについて(重要)
本体のメモリの都合で、モジュールはスクリプトを実行する前に読み込んでおきます。ソースの中の require("名前")(require "名前" / require('名前') を含む)を文字列として拾い、拾ったモジュールの中の require もたどります(最大16モジュール)。実行中の require は、読み込み済みのものを返すだけです。
つまり名前は文字列リテラルで書くのが基本です。
local util = require("util") -- OK: 先読みされる
local name = "util"
local util2 = require(name) -- 先読みされない
組み立てた名前(変数)も、スクリプトのトップレベル近く(関数の呼び出しが深くない所)で呼ぶ分には、その場で読み込めます。関数の奥深くから、先読みされていない名前を読もうとするとエラーになります。モジュールは使う前にスクリプトの先頭で読み込んでおいてください。
デバッグ情報を落としてメモリを減らす(app.cfg の strip_debug)
大きなアプリでLuaのメモリ(200KB)が足りなくなったら、app.cfg に次の1行を書くと、require したモジュールから行番号とローカル変数名を落として読み込みます(コードの大きさが2〜3割減ります)。
strip_debug=true
代わりに、モジュールの中で起きたエラーには行番号が付かなくなります(main.lua 自体はそのまま)。作っている間は外しておき、仕上げで付けるのがおすすめです(例: アプリ「ゾンビTD」)。
従来の lib.lua との関係
同じフォルダに lib.lua があると本体より先に実行される従来の仕組みは、そのまま使えます。新しく作るアプリには require をおすすめします。