الدالة require
حمّل الوحدات الخارجية باستخدام require وافهم التخزين المؤقت للوحدات
الدالة require درس مجاني في Lua Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في 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 interfaceالتخزين المؤقت في package.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 mockتنسيق package.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. يفيد ذلك في التهيئة التي تُجرى مرة واحدة، لكن توخَّ الحذر — فالآثار الجانبية مثل اتصالات الشبكة أو عمليات الملفات تُنفَّذ وقت الاستيراد.
-- 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، وتتطلب B الوحدة A): تخزّن Lua قيمة مؤقتة هي true في package.loaded قبل تنفيذ الوحدة. إذا حاولت 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") مرة ثانية؟
مراجعة: require
الملخص:
- تُحمّل
require(name)الوحدة مرة واحدة وتخزّنها فيpackage.loaded - يعيد ملف الوحدة واجهتها العامة (وعادةً ما تكون جدولًا)
- امسحوا
package.loaded[name]لفرض إعادة التحميل - أضيفوا مسارات البحث المخصصة إلى
package.path - استخدموا
package.preloadللوحدات الموجودة في الذاكرة - تجنبوا التبعيات الدائرية
الأسئلة الشائعة
هل درس «الدالة require» مجاني؟
نعم — نص درس «الدالة require» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Lua Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Lua Academy 4 دروس في المجموع.
ماذا ستتعلم في «الدالة require»؟
حمّل الوحدات الخارجية باستخدام require وافهم التخزين المؤقت للوحدات تتمرن على Lua Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Lua Academy؟
لا تُشترط خبرة سابقة. Lua Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.
كم من الوقت يستغرق درس «الدالة require»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Lua Academy هذا؟
نعم. كل درس في Lua Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.