require関数
requireで外部モジュールを読み込み、モジュールキャッシュの仕組みを理解します。
「require関数」はCoddyKit上の無料Lua Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLua Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Lua Academyコースには全4レッスンが含まれています。
require の仕組み
require(modname) はモジュールを読み込み、その値を返します。.lua ファイルについては package.path を、C ライブラリについては package.cpath を検索します。結果は package.loaded[modname] にキャッシュされます。そのため、次回以降の呼び出しではファイルを再実行せず、キャッシュされた値が返されます。
-- First require: loads and executes math_utils.lua
local math_utils = require("math_utils")
-- Second require: returns cached value (file not re-run)
local math_utils2 = require("math_utils")
print(math_utils == math_utils2) -- true (same object)
print(package.loaded["math_utils"] == math_utils) -- trueモジュールの戻り値
モジュールファイルは値を返す必要があります。通常は関数をまとめたテーブルです。この戻り値が、require が呼び出し側に返す値になります。ファイルが何も返さない場合(または true を返す場合)は、それが require の戻り値になります。
-- mymodule.lua:
-- local M = {}
-- function M.hello() print("Hello from module!") end
-- return M
-- In main script:
local m = require("mymodule")
m.hello() -- Hello from module!
-- The module table is the interfacepackage.loaded のキャッシュ
package.loaded は、モジュール名と読み込まれた値を対応付けるテーブルです。エントリを手動で設定してモックを先行読み込みしたり、nil に設定して再読み込みを強制したりできます(次回の require でモジュールファイルが再実行されます)。
-- Force reload by clearing cache
package.loaded["mymodule"] = nil
local fresh = require("mymodule") -- re-executes the file
-- Preload a mock for testing
package.loaded["db"] = {
query = function() return {} end,
close = function() end,
}
local db = require("db") -- gets the mockpackage.path の形式
package.path は、セミコロンで区切られたパターンのリストです。プレースホルダー ? はモジュール名に置き換えられます(ドットはパス区切り文字に置き換えられます)。package.path の先頭に追加することで、検索対象のディレクトリを追加できます。
print(package.path)
-- typically: ./?.lua;./?.luac;/usr/share/lua/5.4/?.lua;...
-- Add local lib directory
package.path = "./lib/?.lua;" .. package.path
-- Now require("utils") will look in ./lib/utils.luarequire と dofile と loadfile
require: キャッシュし、package.path を検索します。dofile(path): ファイルをすぐに実行し、キャッシュせず、直接のパスを受け取ります。loadfile(path): 実行せずにコンパイルし、関数を返します。モジュールには require を、単発のスクリプトには dofile を使用します。
-- dofile: no caching, direct path
dofile("./scripts/setup.lua")
-- loadfile: compile only, returns function
local fn, err = loadfile("./config.lua")
if fn then
local result = fn() -- execute when ready
end
-- require: best for modules
local json = require("json")ディレクトリ指定にドットを使う require
モジュール名にドットを使うと、サブディレクトリ内のファイルを参照できます。require("utils.string") は、パスパターン内の ? によって utils/string.lua に対応付けられます。これが複数ファイルのライブラリを構成する方法です。
-- Directory structure:
-- lib/
-- utils/
-- string.lua
-- table.lua
-- init.lua
package.path = "./lib/?.lua;" .. package.path
local strUtils = require("utils.string") -- loads lib/utils/string.lua
local tblUtils = require("utils.table") -- loads lib/utils/table.luaモジュール初期化時の副作用
モジュールファイルは、最初に require されたときに一度だけ実行されます。トップレベル(関数の外側)にあるコードは、require 時に実行されます。これは一度だけ行う初期化に便利ですが、ネットワーク接続やファイル操作などの副作用も import 時に実行されるため注意が必要です。
-- counter.lua:
-- local count = 0 -- initialized once on first require
-- local M = {}
-- function M.increment() count = count + 1 end
-- function M.get() return count end
-- return M
local c = require("counter")
c.increment()
c.increment()
print(c.get()) -- 2
local c2 = require("counter")
print(c2.get()) -- 2 (same instance, cached)require でのエラー処理
モジュールファイルに構文エラーがある場合や、読み込み中にエラーが発生した場合、require はエラーを発生させます。エラーメッセージにはモジュール名と、ファイル内部で発生したエラーが含まれます。モジュールの読み込み失敗に適切に対処するには、pcall を使用します。
local ok, mod = pcall(require, "possibly_missing")
if not ok then
print("Module not available:", mod)
-- fall back to alternative or default implementation
mod = {feature = function() return "fallback" end}
end
print(mod.feature())package.preload
package.preload は、モジュール名をキーとしてローダー関数を登録できるテーブルです。require("name") が呼び出されると、Lua はまず preload を確認します。これにより、ファイルを使わずにモジュールを登録できます。組み込み Lua やテストで便利です。
package.preload["mymath"] = function()
return {
double = function(n) return n * 2 end,
triple = function(n) return n * 3 end,
}
end
local m = require("mymath")
print(m.double(5)) -- 10
print(m.triple(5)) -- 15循環 require
循環依存(A が B を require し、B が A を require する場合)は部分的に処理されます。Lua はモジュールを実行する前に、package.loaded に true をプレースホルダーとして保存します。B が A の未完成のテーブルを使おうとすると、不完全な結果を受け取る可能性があります。モジュールを設計する際は、循環依存を避けてください。
-- a.lua: local b = require("b"); local M = {}; M.name = "A"; return M
-- b.lua: local a = require("a"); print("a.name:", a.name); return {}
-- When a.lua is loaded:
-- 1. a starts executing
-- 2. requires b -> b starts executing
-- 3. b requires a -> gets partial a (still loading!)
-- 4. a.name may be nil at step 3
print("Avoid circular requires in module design")クイックチェック
require("mod") を 2 回目に呼び出すと、何が起こりますか?
復習:require
まとめ:
require(name)は 1 回だけ読み込み、package.loadedにキャッシュします- モジュールファイルは公開インターフェース(通常はテーブル)を返します
- 再読み込みするには
package.loaded[name]をクリアします - カスタム検索ディレクトリを追加するには
package.pathに追加します - メモリ上のモジュールには
package.preloadを使います - 循環依存は避けてください
よくある質問
「require関数」レッスンは無料ですか?
はい。「require関数」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Lua Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Lua Academyコースには全4レッスンが含まれています。
「require関数」で何を学びますか?
requireで外部モジュールを読み込み、モジュールキャッシュの仕組みを理解します。 ブラウザで直接実行するハンズオンコードでLua Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Lua Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのLua Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「require関数」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このLua Academyレッスンでコードを書いて実行できますか?
はい。すべてのLua Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。