0Pricing
Lua Academy · レッスン

package.pathとpackage.cpath

LuaモジュールとCモジュールの検索パスを設定します。

「package.pathとpackage.cpath」はCoddyKit上の無料Lua Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLua Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Lua Academyコースには全4レッスンが含まれています。

package.path の内容

package.path は、セミコロンで区切られた検索パターンの文字列です。各パターンには ? のプレースホルダーがあり、そこがモジュール名(ドットはディレクトリ区切り文字に変換されます)に置き換えられます。Lua はファイルが見つかるまで、パターンを順番に試します。

print(package.path)
-- ./?.lua;./?.luac;/usr/local/share/lua/5.4/?.lua;...

-- Dots in module names become directory separators
-- require("foo.bar") -> searches for foo/bar.lua
print(("foo.bar"):gsub("%.", "/"))  -- foo/bar

検索パスの追加

package.path の先頭にパスを追加すると、検索ディレクトリを追加できます。末尾に追加すると、優先度の低い場所になります。新しいパスを必要とする require の呼び出しより前に設定してください。

-- Add multiple directories
package.path = table.concat({
  "./?.lua",
  "./lib/?.lua",
  "./lib/?/init.lua",
  package.path,  -- keep existing paths
}, ";")

-- Now require("json") searches:
-- ./json.lua -> ./lib/json.lua -> ./lib/json/init.lua -> ...

C 拡張用の package.cpath

package.cpath は、C 拡張モジュールの検索パスです(共有ライブラリの場合、Linux では .so、Windows では .dll、macOS では .dylib を使います)。命名規則は、システムの共有ライブラリの規則に従います。

print(package.cpath)
-- ./?.so;/usr/local/lib/lua/5.4/?.so;...

-- Add a local C library directory
package.cpath = "./clib/?.so;" .. package.cpath

-- require("myextension") will now search:
-- ./clib/myextension.so

LUA_PATH 環境変数

LUA_PATH 環境変数は、package.path の初期値を設定します。LUA_PATH 内の ;; はデフォルトパスに置き換えられます。これを使うとスクリプトを変更せずに検索パスを設定できるため、デプロイに便利です。

-- Set before launching Lua:
-- export LUA_PATH="./?.lua;./lib/?.lua;;"
-- The ";;" expands to the built-in default path

-- In Lua, check what was set:
print(package.path)

-- You can also use LUA_CPATH for C paths:
-- export LUA_CPATH="./clib/?.so;;"

package.searchpath

package.searchpath(name, path) は、パス文字列内で name に一致するファイルを検索します。最初に見つかった一致を返し、見つからない場合は nil と、試行したすべての場所を一覧にしたエラーメッセージを返します。実際に読み込まずにファイルを探す場合に便利です。

local file, err = package.searchpath("json", package.path)
if file then
  print("Found:", file)
else
  print("Not found. Tried:\n" .. err)
end

-- Useful for checking if a module exists:
local function moduleExists(name)
  return package.searchpath(name, package.path) ~= nil
end
print(moduleExists("json"))

require の検索アルゴリズム

require("mod") を呼び出すと、Lua は次の順序で処理します:(1) package.loaded を確認、(2) package.preload を確認、(3) package.path で .lua ファイルを検索、(4) package.cpath で C ライブラリを検索します。最初に見つかったものが使用されます。

-- Simulate what require does:
local function myRequire(name)
  -- 1. Check cache
  if package.loaded[name] ~= nil then
    return package.loaded[name]
  end
  -- 2. Check preload
  if package.preload[name] then
    return package.preload[name]()
  end
  -- 3. Search path
  local file = package.searchpath(name, package.path)
  if file then
    return dofile(file)  -- simplified
  end
  error("module not found: " .. name)
end

ローダー関数

package.searchers(以前の package.loaders)は、モジュールの検索と読み込みを試みる関数の配列です。このテーブルにカスタムサーチャーを追加できます。各サーチャーはモジュール名を受け取り、ローダー関数または nil を返します。

-- Add a custom searcher that loads from a table
local builtins = {
  myconfig = function()
    return {host="localhost", port=8080}
  end
}

table.insert(package.searchers, 1, function(name)
  local loader = builtins[name]
  if loader then return loader end
end)

local cfg = require("myconfig")
print(cfg.host, cfg.port)   -- localhost  8080

モジュール名の規則

モジュール名はドットを使った階層構造にします:"mylib.utils"。競合を避けるため、最上位の名前空間にはプロジェクト名または組織名を使うのが一般的です。小文字が標準です。モジュール名でのハイフンは Lua の構文と競合するため避け、代わりにアンダースコアを使ってください。

-- Good: hierarchical, lowercase
-- require("myapp.db.connection")
-- require("myapp.utils.string")

-- Bad: dashes cause syntax issues in dot notation
-- local my-module = require("my-module")  -- SYNTAX ERROR
local mymodule = require("my_module")  -- ok

パスのデバッグ

require がモジュールを見つけられない場合、エラーメッセージに試行したすべてのパスが表示されます。検索順を確認するには package.path を出力してください。特定のモジュールパスを対話的に確認するには package.searchpath を使います。

-- Debug require failures:
local ok, err = pcall(require, "missing_module")
if not ok then
  -- The error message shows all tried paths
  print("require failed:")
  print(err)
  print("\nCurrent package.path:")
  for path in package.path:gmatch("[^;]+") do
    print("  " .. path)
  end
end

デフォルトパスへのリセット

システムのデフォルトを含まない、クリーンで最小限のパスが必要な場合は、package.path 全体をリセットできます。ファイルシステムが制限またはサンドボックス化されている組み込み Lua 環境で便利です。

-- Minimal path for embedded environment
package.path  = "./?.lua;./lib/?.lua"
package.cpath = "./?.so"

-- Or get just the current directory patterns:
local function justLocal()
  return "./?.lua;./?/init.lua"
end

print("Minimal path:", justLocal())

クイックチェック

package.path パターン内の ? は何を表しますか?

復習:package.path

まとめ:

  • package.path:Lua ファイルの検索パターン、? =モジュール名
  • package.cpath:C ライブラリの検索パターン
  • 優先度の高いディレクトリを追加するには先頭に追加します
  • LUA_PATH/LUA_CPATH 環境変数で初期パスを設定します
  • package.searchpath:モジュールを検索可能か確認します
  • package.searchers を使ってカスタムサーチャーを追加します

よくある質問

「package.pathとpackage.cpath」レッスンは無料ですか?

はい。「package.pathとpackage.cpath」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Lua Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Lua Academyコースには全4レッスンが含まれています。

「package.pathとpackage.cpath」で何を学びますか?

LuaモジュールとCモジュールの検索パスを設定します。 ブラウザで直接実行するハンズオンコードでLua Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Lua Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのLua Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「package.pathとpackage.cpath」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このLua Academyレッスンでコードを書いて実行できますか?

はい。すべてのLua Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. require関数
  2. モジュールファイルの作成
  3. package.pathとpackage.cpath
  4. モジュールのパターンとベストプラクティス
← Lua Academyに戻る