0Pricing
Lua Academy · درس

‏package.path وpackage.cpath

اضبط مسارات البحث لوحدات Lua وC

‏package.path وpackage.cpath درس مجاني في Lua Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في 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 -> ...

‏package.cpath لامتدادات C

‏package.cpath هو مسار البحث عن وحدات امتدادات C (المكتبات المشتركة: .so في Linux، و.dll في Windows، و.dylib في macOS). يتوافق اصطلاح التسمية مع اصطلاحات المكتبات المشتركة في النظام.

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) عن ملف يطابق الاسم ضمن سلسلة المسار. ويعيد أول تطابق يعثر عليه، أو 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) البحث عن ملف ‎.lua‎ في package.path، (4) البحث عن مكتبة C في package.cpath. يفوز أول تطابق.

-- 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) هي مصفوفة من الدوال التي تحاول العثور على وحدة وتحميلها. يمكنكم إضافة searchers مخصصة إلى هذا الجدول. يتلقى كل searcher اسم وحدة ويعيد دالة تحميل أو 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: التحقق من إمكانية العثور على وحدة
  • أضيفوا searchers مخصصة عبر package.searchers

الأسئلة الشائعة

هل درس «‏package.path وpackage.cpath» مجاني؟

نعم — نص درس «‏package.path وpackage.cpath» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Lua Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Lua Academy 4 دروس في المجموع.

ماذا ستتعلم في «‏package.path وpackage.cpath»؟

اضبط مسارات البحث لوحدات Lua وC تتمرن على Lua Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Lua Academy؟

لا تُشترط خبرة سابقة. Lua Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.

كم من الوقت يستغرق درس «‏package.path وpackage.cpath»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Lua Academy هذا؟

نعم. كل درس في Lua Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. الدالة require
  2. كتابة ملف وحدة
  3. ‏package.path وpackage.cpath
  4. أنماط الوحدات وأفضل الممارسات
← العودة إلى Lua Academy