Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

الـ 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).

challenge icon

التحدي

سهل

اكتب دالة 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
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس Logic & Flow