الـ Metamethods الحسابية - الجزء الثاني
جزء من قسم Logic & Flow في رحلة Lua على Coddy — الدرس 22 من 54.
بناءً على الجمع والطرح، يمكنك أيضاً تحديد سلوك الضرب والقسمة لجداولك باستخدام metamethods __mul و __div. تعمل هذه بنفس الطريقة التي تعمل بها __add و __sub، لكنها تستجيب للمؤثرين * و /.
تعتبر الـ metamethod المسماة __mul مفيدة بشكل خاص عندما تريد تغيير حجم (scale) قيم الجدول. على سبيل المثال، ضرب متجه في رقم (يسمى كمية قياسية أو scalar) يجب أن يضرب كل مكون من مكوناته:
local vector = {x = 3, y = 4}
local meta = {
__mul = function(a, b)
local scalar = type(a) == "number" and a or b
local vec = type(a) == "table" and a or b
return {x = vec.x * scalar, y = vec.y * scalar}
end
}
setmetatable(vector, meta)
local scaled = vector * 2
print(scaled.x, scaled.y) -- المخرجات: 6 8لاحظ كيف تتحقق الدالة من أي معامل هو الرقم وأيهما هو الجدول. هذا يسمح لكل من vector * 2 و 2 * vector بالعمل بشكل صحيح.
تعمل الـ metamethod المسماة __div بشكل مشابه لعملية القسمة:
local meta = {
__div = function(a, b)
return {x = a.x / b, y = a.y / b}
end
}
setmetatable(vector, meta)
local divided = vector / 2
print(divided.x, divided.y) -- الناتج: 1.5 2تُكمل هذه التوابع الوصفية (metamethods) العمليات الحسابية الأساسية لأنواعك المخصصة، مما يمنحك تحكماً كاملاً في كيفية تصرف العوامل الحسابية مع جداولك (tables).
التحدي
سهلاكتب دالة scaleVector تأخذ x و y و scalar وتعيد المتجه المقياس كسلسلة نصية منسقة.
قم بإنشاء جدول متجه (vector table) بالإحداثيات المعطاة، وأرفق جدولاً وصفياً (metatable) باستخدام الطريقة الوصفية __mul لتمكين الضرب القياسي، واضرب المتجه في القيمة القياسية باستخدام عامل الضرب *، ثم أعد النتيجة.
المنطق:
- أنشئ جدول متجه بمفاتيح
xوyمضبوطة على الإحداثيات المقدمة - أنشئ جدولاً وصفياً (metatable) باستخدام
__mulيتعامل مع الضرب بين المتجه والقيمة القياسية - يجب أن تتحقق دالة
__mulمن أي معامل هو الرقم وأيهما هو الجدول - أعد جدولاً جديداً بقيم
x = vec.x * scalarوy = vec.y * scalar - أرفق الجدول الوصفي بجدول المتجه باستخدام
setmetatable() - اضرب المتجه في القيمة القياسية باستخدام
vector * scalar - أعد النتيجة كسلسلة نصية بالتنسيق
"x y"(قيم x و y مفصولة بمسافة)
المعاملات:
x(number): إحداثي x للمتجهy(number): إحداثي y للمتجهscalar(number): القيمة القياسية لضرب المتجه بها
المخرجات: المتجه المقياس كسلسلة نصية بالتنسيق "x y" (string)
ورقة مرجعية
تحدد الطرق الوصفية (metamethods) __mul و __div سلوك الضرب والقسمة للجداول، استجابةً للمعاملين * و /.
تُعد الطريقة الوصفية __mul مفيدة لتغيير حجم (scaling) قيم الجدول. عند ضرب متجه (vector) في قيمة عددية (scalar)، تحقق من أي المعاملات هو الرقم وأيها هو الجدول للسماح بكل من vector * 2 و 2 * vector:
local vector = {x = 3, y = 4}
local meta = {
__mul = function(a, b)
local scalar = type(a) == "number" and a or b
local vec = type(a) == "table" and a or b
return {x = vec.x * scalar, y = vec.y * scalar}
end
}
setmetatable(vector, meta)
local scaled = vector * 2
print(scaled.x, scaled.y) -- المخرجات: 6 8تعمل الطريقة الوصفية __div بشكل مشابه بالنسبة للقسمة:
local meta = {
__div = function(a, b)
return {x = a.x / b, y = a.y / b}
end
}
setmetatable(vector, meta)
local divided = vector / 2
print(divided.x, divided.y) -- المخرجات: 1.5 2جرّب بنفسك
function scaleVector(x, y, scalar)
-- اكتب الكود هنا
end
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس Logic & Flow
1التكرار المتقدم عبر الجداول
التكرار باستخدام pairs()التكرار باستخدام ipairs()pairs() مقابل ipairs()مراجعة - ورقة الشخصية4مقدمة إلى Metatables
ما هو الـ Metatable؟setmetatable و getmetatableالـ Metamethod المسماة __indexالـ Metamethod المسماة __newindexالـ Metamethod المسماة __tostringالـ Metamethods الحسابية - الجزء الأولالـ Metamethods الحسابية - الجزء الثانيملخص - جدول للقراءة فقط2المزيد من دوال مكتبة Table
table.concat()إنشاء الجداول و unpack()table.sort()فرز مخصص باستخدام الدوالمراجعة - لوحة أعلى النتائج