المُهيّئ والموصّلات
في الدرس السابق تعلمنا كيف ننشئ أصنافاً ونستخدم دوال مثل set_name و get_name لتعيين وقراءة البيانات. لكن كتابة هذه الدوال لكل متغير أمر متعب ومُكرر! في هذا الدرس سنتعلم طريقتين أفضل:
initialize- لتعيين البيانات عند إنشاء الكائن- الموصّلات (
attr_reader,attr_writer,attr_accessor) - لإنشاء دوال القراءة والكتابة تلقائياً
دالة المُهيّئ (initialize)
المشكلة بدون initialize
هذا يتطلب خطوتين إضافيتين بعد إنشاء الكائن!
الحل: استخدام initialize
initialize هي دالة خاصة تُستدعى تلقائياً عند إنشاء كائن جديد بـ new:
أفضل بكثير! نُمرر كل البيانات دفعة واحدة.
قواعد المُهيّئ
1. الاسم ثابت
يجب أن يكون الاسم بالضبط initialize (بدون اختصار أو تغيير):
2. المُعاملات الافتراضية
يمكنك تحديد قيم افتراضية للمُعاملات:
3. المُهيّئ لا يُرجع قيمة
لا تستخدم return في المُهيّئ - روبي تتجاهله وتُرجع الكائن الجديد:
4. استدعاء دوال أخرى في المُهيّئ
يمكنك استدعاء دوال أخرى داخل المُهيّئ:
مشكلة القراءة والكتابة
حتى مع initialize، ما زلنا نحتاج لكتابة دوال للقراءة والكتابة:
هذا كثير من الشيفرة المتكرر! هنا تأتي الموصّلات.
الموصّلات (Attribute Accessors)
الموصّلات هي اختصارات تُنشئ دوال القراءة والكتابة تلقائياً.
attr_reader - للقراءة فقط
تُنشئ دالة قراءة (getter) للمتغير:
attr_reader :name تُنشئ هذه الدالة تلقائياً:
attr_writer - للكتابة فقط
تُنشئ دالة كتابة (setter) للمتغير:
attr_writer :theme تُنشئ هذه الدالة تلقائياً:
attr_accessor - للقراءة والكتابة معاً
تُنشئ دالتي القراءة والكتابة معاً:
attr_accessor :name تُنشئ هاتين الدالتين تلقائياً:
متى نستخدم كلاً منها؟
| الموصّل | الاستخدام | مثال |
|---|---|---|
attr_reader | بيانات لا تتغير | id, created_at, email |
attr_writer | بيانات تُكتب فقط (نادر) | password, secret_key |
attr_accessor | بيانات تُقرأ وتُكتب | name, age, status |
مثال عملي: حساب المستخدم
الجمع بين الموصّلات والدوال المُخصصة
أحياناً تحتاج لتحقق أو معالجة قبل تعيين القيمة. في هذه الحالة، اكتب دالتك الخاصة:
مثال شامل: صنف السيارة
جدول مقارنة
| الطريقة | قبل | بعد |
|---|---|---|
| الإنشاء | p = Person.new ثم p.set_name("أحمد") | p = Person.new("أحمد") |
| القراءة | كتابة def name; @name; end | attr_reader :name |
| الكتابة | كتابة def name=(v); @name = v; end | attr_writer :name |
| كلاهما | كتابة دالتين | attr_accessor :name |
أخطاء شائعة
1. نسيان الرمز : قبل اسم المتغير
2. استخدام @ مع الموصّلات
3. استدعاء الموصّل داخل الصنف بدون self
داخل الصنف، استخدم @variable مباشرة أو self.variable:
4. محاولة الكتابة مع attr_reader
ملخص
| المفهوم | الوظيفة | مثال |
|---|---|---|
initialize | تهيئة الكائن عند الإنشاء | def initialize(name); @name = name; end |
attr_reader | إنشاء دالة قراءة | attr_reader :name → def name; @name; end |
attr_writer | إنشاء دالة كتابة | attr_writer :name → def name=(v); @name = v; end |
attr_accessor | قراءة + كتابة | attr_accessor :name → كلا الدالتين |
تمرين: صنف Book مع المُهيّئ والموصّلات
حان وقت التطبيق! في محرر الشيفرة على اليسار:
المطلوب:
-
أنشئ صنف
Bookيحتوي على:attr_reader :title, :author(العنوان والكاتب لا يتغيران)attr_accessor :pages_read(الصفحات المقروءة تتغير)- دالة
initializeتستقبلtitle,author,total_pages - دالة
progressتُرجع نسبة الإنجاز كنص
-
أنشئ كتاباً بعنوان "تعلم روبي"، للكاتب "أحمد"، وعدد صفحاته 200
-
اقرأ 50 صفحة (عيّن
pages_read = 50) -
اطبع العنوان والكاتب ونسبة الإنجاز
الناتج المتوقع:
تلميحات:
- استخدم
@total_pagesلتخزين عدد الصفحات الكلي (لا تحتاج موصّل له) - نسبة الإنجاز =
(@pages_read.to_f / @total_pages * 100).to_i - لا تنسَ تعيين
@pages_read = 0في المُهيّئ كقيمة أولية
تذكّر:
initializeتُسهّل إنشاء الكائنات بتمرير البيانات مباشرة. الموصّلات (attr_reader,attr_writer,attr_accessor) تُوفّر الوقت بإنشاء دوال القراءة والكتابة تلقائياً. في الدرس القادم سنتعلم الوراثة لإنشاء أصناف ترث خصائص وسلوكيات من أصناف أخرى!