English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
المكون يشبه مكتبة محكمة، بدءًا من Lua 5.1، أضاف Lua ميكانيكية إدارة مكونات قياسية، يمكن وضع بعض الكود العام في ملف واحد واستدعاء هذه الكود كواجهة API في مكان آخر، مما يساعد في إعادة استخدام الكود وتقليل توتر الكود.
مكونات Lua من جدول يتكون من العناصر المعروفة مثل المتغيرات والوظائف، لذا إنشاء مكون هو بسيط، فقط إنشاء جدول، ثم وضع المكونات التي تحتاج إلى تصدير مثل القيم الثابتة والوظائف فيه، وأخيرًا إرجاع هذا الجدول فقط. إليك مثال على إنشاء مكون مخصص module.lua، شكل ملف الكود هو كالتالي:
-- اسم الملف هو module.lua -- تعريف وحدة باسم module module = {} -- تعريف معادلة ثابتة module.constant = "هذه هي معادلة ثابتة" -- تعريف وظيفة function module.func1() io.write("هذه هي وظيفة عامة!\n") end local function func2() print("هذه هي وظيفة خاصة!") end function module.func3() func2() end return module
من الممكن أن نرى أن بنية الوحدة هي بنية table، لذا يمكننا معالجة استدعاء معادلات أو وظائف الوحدة بنفس الطريقة التي نتعامل فيها مع عناصر table.
يُعرف func2 كمتغير محلي للبرنامج، مما يعني أنه وظيفة خاصة، لذا لا يمكن الوصول إلى هذه الوظيفة الخاصة في الوحدة من الخارج، بل يجب استدعاؤها عبر وظائف عامة في الوحدة.
يقدم Lua وظيفة تُدعى require لتحميل الوحدات. لإجراء تحميل وحدة، يكفي فقط تنفيذ الاتصال ببساطة. على سبيل المثال:
require("<اسم الوحدة>")
أو
require "<اسم الوحدة>"
بعد تنفيذ require سيتم إرجاع table يحتوي على معادلات أو وظائف الوحدة، بالإضافة إلى تعريف متغير عالمي يحتوي على هذا table.
نتيجة تنفيذ الكود أعلاه هي:
هذه هي معادلة ثابتة هذه وظيفة خاصة!
أو تعريف اسم بديل للوحدة المحملة لسهولة الاستدعاء:
نتيجة تنفيذ الكود أعلاه هي:
هذه هي معادلة ثابتة هذه وظيفة خاصة!
بالنسبة للوحدات المخصصة، ملف الوحدة ليس له دليل ملف معين يمكن أن يكون، ووظيفة require لديها استراتيجية تحميل المسار الخاصة بها، حيث ستحاول تحميل الوحدة من ملف Lua أو مكتبة برنامج C.
يتم حفظ مسار البحث عن ملفات Lua في المتغير العالمي package.path، عند بدء Lua، يتم تحديد هذا المتغير باستخدام قيمة متغير البيئة LUA_PATH. إذا لم يتم العثور على هذا المتغير البيئي، يتم استخدام مسار افتراضي محدد أثناء التجميع لتحديد هذا المتغير.
بالطبع، إذا لم يكن متغير البيئة LUA_PATH موجودًا، يمكن أيضًا تعديل إعداداته، افتح ملف .profile في مجلد المستخدم الحالي (إذا لم يكن موجودًا، يمكنك أيضًا فتح ملف .bashrc)، على سبيل المثال، أضف مسار "~/lua/" إلى متغير البيئة LUA_PATH:
#LUA_PATH export LUA_PATH="~/lua/?.lua;;"
مسار الملفات يتم فصله بـ ";"، والثلاث نقاط في النهاية ";;" تعني إضافة المسار الجديد إلى المسار الافتراضي.
ثم، تحديث معلمات متغير البيئة لجعلها نافذة الفعالية.
source ~/.profile
في هذه الحالة، لنفترض أن قيمة package.path هي:
/Users/dengjoe/lua/?.lua;./?.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/?/init.lua;/usr/local/lib/lua/5.1/?.lua;/usr/local/lib/lua/5.1/?/init.lua
لذا عند استدعاء require("module") سيتم محاولة فتح هذا مجلد ملفات للبحث عن الهدف.
/Users/dengjoe/lua/module.lua; ./module.lua /usr/local/share/lua/5.1/module.lua /usr/local/share/lua/5.1/module/init.lua /usr/local/lib/lua/5.1/module.lua /usr/local/lib/lua/5.1/module/init.lua
إذا تم البحث عن ملف الهدف، سيتم استدعاء package.loadfile لتحميل المodule. وإلا، سيتم البحث عن مكتبة البرنامج C.
يتم الحصول على مسار ملف البحث من المتغير العالمي package.cpath، وهذا المتغير يتم تحديده من خلال متغير بيئي LUA_CPATH.
استراتيجية البحث تشبه السابقة، ولكن الآن يتم البحث عن ملفات من نوع so أو dll. إذا تم العثور عليها، فإن require سيقوم بتحميلها باستخدام package.loadlib.
من السهل دمج Lua مع C، يمكنك كتابة مكتبات C لمكتبة Lua.
مختلف عن كتابة المجموعات في Lua، يجب أولاً تحميل وتوصيل مكتبة C قبل استخدامها، وفي معظم الأنظمة، يمكن تحقيق ذلك بسهولة من خلال ميكانيكية الروابط الديناميكية.
تقدم Lua جميع الوظائف للروابط الديناميكية من خلال دالة loadlib. لدى هذه الدالة أثنين من المعلمات: مسار المكتبة واسم دالة التمهيد. لذا، مثال التطبيق النموذجي هو:
local path = "/usr/local/lua/lib/libluasocket.so" local f = loadlib(path, "luaopen_socket")
تقوم دالة loadlib بتحميل المكتبة المحددة وتوصيلها إلى Lua، ولكنها لا تفتح المكتبة (أي لم تتم دعوة دالة التمهيد)، على العكس، فإنها تعود دالة التمهيد كوظيفة في Lua، وبالتالي يمكننا تفعيلها مباشرة في Lua.
إذا حدث خطأ أثناء تحميل المكتبة الديناميكية أو البحث عن دالة التمهيد، فإن loadlib سيعود nil ورسالة الخطأ. يمكننا تعديل الجملة السابقة ليتحقق من الخطأ ثم يطبع دالة التمهيد:
local path = "/usr/local/lua/lib/libluasocket.so" -- أو path = "C:\\windows\\luasocket.dll"، هذا هو منصة Windows local f = assert(loadlib(path, "luaopen_socket")) f() -- فتح المكتبة فعلياً
في العادة، نأمل أن تحتوي مكتبات النشر الثنائية على ملف stub مشابه للجملة الكودية السابقة، يمكنك وضع مكتبة ثنائية في مجلد أي، بشرط تعديل مسار ملف stub لمكتبة الثنائية الفعلية.
أضف مجلد stub الموجود إلى LUA_PATH، وبعد ذلك يمكنك استخدام دالة require لتحميل مكتبة C.