Ruby Programming

إتقان call() و send() في روبي

Spread the love

محتويات الجدول

  1. ما هو call() في روبي؟
  2. ما هو send() في روبي؟
  3. التطبيقات العملية لـ call() و send()
  4. الخاتمة
  5. الأسئلة الشائعة

ما هو call() في روبي؟

طريقة call()، المعروفة أيضًا باسم “طريقة الاتصال” أو “الطريقة القابلة للاتصال”، تسمح لك باستدعاء طريقة على كائن باستخدام عامل تشغيل طريقة الاتصال (). هذا يحول الكائنات إلى كيانات قابلة للاتصال، مشابهة للدوال أو الإجراءات. يمكن لأي فئة تعريف طريقة call()، مما يجعل مثيلاتها قابلة للاتصال.


class Adder
  def initialize(x)
    @x = x
  end

  def call(y)
    @x + y
  end
end

adder = Adder.new(5)
result = adder.call(3)  # ستكون النتيجة 8
result = adder.(3)      # مكافئ باستخدام عامل تشغيل طريقة الاتصال
puts result             # الإخراج: 8

call() لا تقدر بثمن لإنشاء دوال مخصصة أو كتل رمزية يمكن تمريرها وتنفيذها لاحقًا. إنها حجر الزاوية لقدرات البرمجة الوظيفية في روبي.

ما هو send() في روبي؟

طريقة send() تستدعي طريقة ديناميكيًا على كائن، وتقبل اسم الطريقة كسلسلة أو رمز. هذا يسمح بالتلاعب في وقت التشغيل بالكائنات وطرقها.


class Greeter
  def hello(name)
    "Hello, #{name}!"
  end

  def goodbye(name)
    "Goodbye, #{name}!"
  end
end

greeter = Greeter.new
message = greeter.send(:hello, "World")  # ستكون الرسالة "Hello, World!"
puts message

message = greeter.send("goodbye", "World") # ستكون الرسالة "Goodbye, World!"
puts message

يتم تمرير اسم الطريقة (`:hello` أو `”goodbye”`) كوسيطة إلى send()، مما يوفر استدعاء طريقة مرن، حتى بناءً على شروط ديناميكية. ومع ذلك، فإن الحذر ضروري عند استخدام send() مع إدخال غير موثوق به لمنع الثغرات الأمنية.

التطبيقات العملية لـ call() و send()

توفر call() و send() مزايا متميزة:

  • call(): مثالية لإنشاء كائنات قابلة للاتصال، وتنفيذ الاستراتيجيات (مثل خوارزميات الفرز المختلفة)، والعمل مع مفاهيم البرمجة الوظيفية مثل لامدا و بروكس. توفر بناء جملة أنظف وأكثر قابلية للقراءة من send() للطرق المحددة مسبقًا.
  • send(): مفيدة للبرمجة التجريبية، وإرسال الطرق الديناميكي بناءً على شروط وقت التشغيل، وإنشاء واجهات برمجة تطبيقات مرنة. إنها مفيدة بشكل خاص عندما يكون اسم الطريقة غير معروف في وقت التجميع. ومع ذلك، فإن الإفراط في الاستخدام قد يقلل من قابلية قراءة التعليمات البرمجية وصيانتها.

مثال: نمط الاستراتيجية مع call()


class SortStrategy
  def call(array)
    raise NotImplementedError, "يجب على الفئات الفرعية تنفيذ طريقة الاتصال"
  end
end

class BubbleSort < SortStrategy
  def call(array)
    # تنفيذ فرز الفقاعات ... (تم حذف التنفيذ للاختصار)
  end
end

class QuickSort < SortStrategy
  def call(array)
    # تنفيذ فرز سريع ... (تم حذف التنفيذ للاختصار)
  end
end

sorter = BubbleSort.new
sorted_array = sorter.call([3, 1, 4, 1, 5, 9, 2, 6])

هذا يوضح كيف تقوم call() بتنفيذ نمط الاستراتيجية بشكل أنيق.

الخاتمة

call() و send() أداتان قويتان في روبي. توفر call() نهجًا وظيفيًا أنيقًا لإنشاء كائنات قابلة للاتصال، بينما توفر send() استدعاء طريقة ديناميكي. إن فهم نقاط القوة والضعف الخاصة بهما يمكّن المطورين من اختيار الطريقة المناسبة لكل مهمة، مما يحسن مرونة التعليمات البرمجية وصيانتها. استخدم send() بحذر، خاصةً مع الإدخال غير الموثوق به، للتخفيف من المخاطر الأمنية.

الأسئلة الشائعة

  • س: ما هي الآثار الأمنية لاستخدام send()؟
    ج: استخدام send() مع إدخال غير موثوق به يمكن أن يسمح بتنفيذ خبيث لطرق عشوائية، مما يخلق ثغرات أمنية. قم دائمًا بتطهير و التحقق من صحة الإدخال قبل استخدام send().
  • س: هل يمكنني استخدام call() مع أي طريقة؟
    ج: لا، call() مخصصة للطرق المسماة call().
  • س: هل send() أسرع من استدعاء طريقة مباشرة؟
    ج: لا، send() ينطوي على بحث، مما يجعله أبطأ. استخدمه فقط عندما يكون الاستدعاء الديناميكي ضروريًا.
  • س: ما هو الفرق بين send و public_send؟
    ج: public_send يستدعي فقط الطرق العامة، مما يعزز الأمان عن طريق منع الوصول إلى الطرق الخاصة/المحمية. send يمكنه استدعاء طرق بأي مستوى رؤية.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *