Jump to content

meta tables


Recommended Posts

السلام عليكم شباب, كيف الحال؟

اليوم جايب لكم شرح جداول الميتا

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 : .. 

ان شاء الله فهمتم الشرح

اي استفسار ضع ردك

:mrgreen:

Edited by Guest
  • Like 1
  • Thanks 1
Link to comment

oopبهذه الوظيفة نسوي ال

وهذا مثال بسيط :D

Window = { } 
Window.__index = Window 
setmetatable(Window, {__call = function (win, ...) return win.new(...) end}) 
  
function Window.new( ) 
    local self = {x = 0, y = 0, w = 400, h = 500, title = "Title"} 
    self.window = guiCreateWindow(self.x, self.y, self.w, self.h, self.title, false) 
    if not isElement(self.window) then return end 
    return setmetatable(self, Window) 
end 
  
function Window:setTitle(title) 
    if type(title) == "string" then 
        self.title = title 
        return guiWindowSetTitle(self.window, title) 
    end 
    return false 
end 
  
function Window:getTitle( )  
    return self.title 
end 
  
  
local window = Window( ) 
window:setTitle("New Title") 
outputChatBox(window:getTitle( )) 
-- or 
outputChatBox(window.title) 

  • Like 1
Link to comment

oopبهذه الوظيفة نسوي ال

وهذا مثال بسيط :D

Window = { } 
Window.__index = Window 
setmetatable(Window, {__call = function (win, ...) return win.new(...) end}) 
  
function Window.new( ) 
    local self = {x = 0, y = 0, w = 400, h = 500, title = "Title"} 
    self.window = guiCreateWindow(self.x, self.y, self.w, self.h, self.title, false) 
    if not isElement(self.window) then return end 
    return setmetatable(self, Window) 
end 
  
function Window:setTitle(title) 
    if type(title) == "string" then 
        self.title = title 
        return guiWindowSetTitle(self.window, title) 
    end 
    return false 
end 
  
function Window:getTitle( )  
    return self.title 
end 
  
  
local window = Window( ) 
window:setTitle("New Title") 
outputChatBox(window:getTitle( )) 
-- or 
outputChatBox(window.title) 

منور تنطيل و تسلم علي المثال :D

Link to comment
p_581iy81.jpg

بصراحة لم تخترع الكلمات لوصف شعوري بعد *^*

شرح اكثر من رائع ومفيد جداً وخاصتاً انه جديد وسهل و واضح :wink:

بالتوفيق عزيزي :fadein:

=D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D>

Deadpool - ديدبول

منور يا ملك الملوك يا بنرس البرانيس

:lol: حمستني بردك

منور موضير ض2

Link to comment
شرح رائع يعطيك العافية

+

يا ريت تعمل شرح لل

database

يعطيك العافية

شرح مختصر لكن يفهم :]

الله يعطيك العافية زي ما علمتني :]

وننتظرك بشروح جديدة

منورين الموضوع

-------------

بلنسبة لل

database

نفس شغل

executeSQLQuery 

لكن الفرق انه لكل شيء فنكشنات مختلفة

وتقدر تربطه بقاعدة خارجية

Link to comment
  • 3 weeks later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...