السلام عليكم شباب, كيف الحال؟
اليوم جايب لكم شرح جداول الميتا
Note : ألشرح مختصر
Note : جداول الميتا ليست للجداول فقط بل يمكن استعمالها مع متغيرات اخري
نبدأ علي بركة الله
________________________
اولاً جداول الميتا هي جداول تحتوي علي احداث تتعرف مثل المفاتيح في الجدول
Note : المفاتيح تعرف بأسم
Meta Methods
وكلها تبدأ ب __
وش تقدر تسوي بجداول الميتا؟
واحدة من خصائصها انك تقدر تخلي الشيء المطبق عليه الميتا تيبل
عند استدعائه تستدعيه كأنه فنكشن و يسوي الشيء المربوط له
لكنها تستعمل غالباً في عمل OOP
يعني لو انت تبي تتعلم OOP
انصحك بتعلم الميتا تيبل اولاً
يعني الحين عندنا جدول بلمنظر ذا
Table = {["Test"] = 4, ["Test2"] = 3}
واجينا استدعينا قيمة مفتاح
لكن المفتاح غير مووجود ونبي نسوي وظيفة اذا كان غير موجود نستعمل الحدث
__newindex
يعني مثل احداث الام تي اي العادية لكن الفرق انها للجداول
مثل
__index
و
__newindex
ذي احداث للميتا تيبل
الحين كيف نربط ميتا تيبل بتيبل عادي؟
نستعمل وظيفة
setmetatable
هذي الوظيفة تحط لجدول ميتا تيبل له
مثال
Syntax --
setmetatable(table TheTable, table metatable)
TheTable : هو الجدول اللي تبي تربط له ميتا تيبل
metatable : الميتا تيبل اللي تبي تربطها للجدول
مثال :
metatable = {} -- هذي الميتا تيبل حقتنا اللي ما تحتوي شيء حالياً
local Table = setmetatable({}, metatable)
وبكذا نكون ربطنا تيبل بميتا تيبل
Note : setmetatable ترجع اول ارقمنت لها يعني مو لازم تسوي متغير للجدول مشان تركب له ميتا تيبل
الحين الميتا تيبل وش نحط فيها؟
نحط فيها احداث
وكيف نحط احداث؟
نحط المفاتيح ألمميزة
مثال
__index and __newindex
هذول يتنفذو عند التعديل علي التيبل و كل واحد يتنفذ في لحظة معينة
مثل
__index
Note : فيه احداث كثيرة بس هذول اسهلهم
هذا يتنفذ يوم نروح نجيب مفتاح من جدول وما يلاقيه
طيب كيف تربط فنكشن بحدث (مفتاح ) داخل الميتا تيبل؟
اول شيء نحط المفتاح و نحط قيمته الفنكشن المطلوب تنفيذه لما يتنفذ الحدث
مثال :
metatable = {
__index = function ()
print("المفتاح غير موجود")
end
}
MyTable = setmetatable({["DABL"] = 1}, metatable) -- كذا معنا جدول مربوط بلميتا تيبل
print(tostring(MyTable["DABL"])) -- نستدعي قيمة المفتاح دابل
print(tostring(MyTable["Marshmello"])) -- نستدعي قيمة المفتاح مارشميلو
(
لو تبي تجرب امثلة جرب هنا
http://www.lua.org/cgi-bin/demo
مشان يكون الشرح اسهل)
الحين اول استدعاء رح يطلع 1 لان قيمة المفتاح
["DABL"]
في الجدول 1
لكن ثاني استدعاء راح يخلي الرسالة تطلع اللي هي
print("المفتاح غير موجود")
لاننا استدعينا مفتاح غير موجود
اللي هو
["Marshmello"]
مشان كذا الوظيفة المربوطة لايفينت __index
اتنفذت
طيب ندخل علي البارمترات
كل ايفينت له بارمترات خاصة فيه مثل الام تي اي نفس الوضع
مثلاً البارمتر حق
__index
عنده اثنين الاول هو الجدول
والثاني هو المفتاح اللي حاولنا استدعاء و فشل , مثال
metatable = {
__index = function (TheTable, TheKey)
print(tostring(TheTable).. " غير موجود في "..TheKey)
end
}
MyTable = setmetatable({["DABL"] = 1}, metatable) -- كذا معنا جدول مربوط بلميتا تيبل
print(tostring(MyTable["Marshmello"])) -- نستدعي قيمة المفتاح مارشميلو
طبعاً قيمة المفتاح مارشميلو غير موجودة مشان كذا بينفذ الوظيفة اللي هي
function (TheTable, TheKey)
print(tostring(TheTable).. " غير موجود في "..TheKey)
end
المربوطة له
لو لاحظت بتلاقي اني حاطت بارمترين في الفنكشن
اللي هما
TheTable, TheKey
هذول اتعرفو من ال__index
وفيه احداث ثانية لها بامترات خاصة بها
وهذا كان كيفية استعمال الميتا تيبل مع شرح
__index
باقي الحداث تجدها هنا :
http://lua-users.org/wiki/MetatableEvents
______________________
ونروح ل
getmetatable
هذا يجيب الميتا تيبل حقت جدول معين
مثلاً
Tab = setmetatable({}, {__index = function () print("Hello") end})
print(tostring(getmetatable(Tab))) --> table: 0x14bb510
مفتاح
__tostring
عند استعمال
tostring
علي الجدول تتنفذ الوظيفة المربوطة له
مثال
MyTable = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100}
metatable = {
__tostring = function (TheEditingTable)
local Number = 0
for Key, Value in ipairs(MyTable) do
Number = Number + Value
end
return Number
end
}
setmetatable(MyTable, metatable)
print(MyTable) --> 550
البارامترات المررة للفنكشن
1- التيبل اللي مربوط له الميتا تيبل
. قبل ما تطبعه tostring تعمل للي بتطبعه print ملاحظة : الوظيفة
مفتاح
__eq
يستعمل في التحقق من المساواة يعني اذا جدول يساوي جدول
يرجع لك true
طيب كيف تعمل؟
لازم الفنكشن المربوط بلمفتاح يكون يرجع نفس القيمة حقت المفتاح اللي بلجدول الاخر
مثال :
Table = {} -- ننشأ جدول فارغ
Table2 = {} -- ننشأ جدول فارغ اخر
MetaTable = { __eq = function () return "Lua Testing" end} -- جدول ميتا فيه المفتاح __eq
MetaTable2 = { __eq = function () return "Lua Testing" end} -- ننشأ جدول ميتا اخر فيه نفس المفتاح
setmetatable(Table, MetaTable) -- نحط لاول جدول اول ميتا تيبل
setmetatable(Table2, MetaTable2) -- نحط لثاني جدول ثاني ميتا تيبل
print(Table == Table2) -- نتحقق اذا كان الجدول الاول يساوي الجدول الثاني
-- طبعا راج يرجع true
--لان الفنكشن المربوط بلمفتاح رجع نفس القيمة
-- اللي هي "Lua Testing"
طيب وش يصير لو غيرنا القيم ألمرجعة و خلينها مختلفة عن بعض؟
بيرجع لك false
لان الجدول لا يساوي الجدول الاخر
مفتاح
__len
يتحكم في المعامل
#
بلنسبة للججدول
يعني مثلاً
لو سوينا كذا
Table = {"Name", "Name2", "SomeGuy", "NoOne"}
print(#Table) --> 4
هذا راح يرجع 4
لان اكبر اندكس في الجدول 4
Note : لو كنت حاط اندكس بالترتيب وحطيت اندكس اكبر من الاندكسات الأخرى بكثر ما يطلعها لك,
كـ مثال لكلامي :
t = {
[1] = 1,
[2] = 2,
[3] = 3,
[200] = 200
}
print ( #t ) -- 3
شكرا خاص للاخ شاطح علي الاضافة
ونكمل في شرحنا
طيب لو نبيه يغير القيمة؟بدون ما نزيد عدد القيم نستعمل
المفتاح __len
والقيمة اللي ارجعها الفنكشن المربوط له بيطلعها
مثال
Table = {} -- ننشأ جدول فارغ
MetaTable = { __len = function () return 90 end} -- جدول فيه المفتاح ويرجع رقم 90
setmetatable(Table, MetaTable) -- نربط الجدولين ببعض
print(#Table) --> 90
هذا المفروض يرجع 0 لان الجدول فارغ
لكنه ارجع 90
لان الفنكشن يرجع 90
مفتاح
__metatable
هذا يخبي الميتا تيبل حقت التيبل يوم نستعمل وظيفة
getmetatable
كيف يخبيها؟
يعني لما تجيب الميتا تيبل حقت تيبل يرجع لك قيمة ثانية من اختيارك
القيمة ما راح تكون مرجعة من فنكشن
يعني سوي متغير و حط القيمة لا تسوي فنكشن يرجع قيمة كذا يعني
MetaTable = {__metatable = "Test"}
كذا راح يرجع "Test'
لكن لو سويت فنكشن بيرجع الفنكشن
مثال :
Table = {} -- جدول عادي
MetaTable = {__metatable = "Haha you were tricked !"}
setmetatable(Table, MetaTable)
print(tostring(getmetatable(Table))) --> Haha you were tricked !
لو لاحظت اننا حاولنا نجيب الميتا تيبل بس ما جت لاننا مخلينه يرجع قيمة ثانية
Mathematic Operators
__unm
__add
__sub
__mul
__div
__mod
__pow
__concat
نبدأ ب
__unm
لو حولت الجدول لسالب
بيرجع لك الرقم اللي انت مرجعه بلفنكشن المتصل به
مثال :
Tab = setmetatable({}, {__unm = function () return (5 * 5) end})
print(-Tab) --> 25 (5 × 5)
__add
يوم تجمع الجدول + كائن
يحط الرقم المربوط للميتا تيبل بكل بساطة
Note : لو الشيئين اللي بينجمعو جداول الجدول اللي علي اليسار بينفحص الاول ثم الايمن
مثال :
Tab = setmetatable({}, {__add = function () return 5 end})
print(100 + Tab) --> 5
__sub
نفس الشيء حق
__add
لكن هذا يعمل للطرح " - "
طبعا كل الوظائف التالية نفس الشيء
ولكل واحدة علامة خاصة تعمل بها
وهذول هما
:
__sub : -
__mul : *
__div : /
__mod : %
__pow : ^
__concat : ..
ان شاء الله فهمتم الشرح
اي استفسار ضع ردك