في بعض اللهجات الإنجليزية، عندما تقول "two for" بسرعة، يبدو الأمر وكأنك تقول "two fer". و"two-for-one" طريقة للقول إنه إذا اشتريت واحدة، فستحصل على أخرى مجانًا. لذلك غالبًا ما توحي عبارة "two-fer" بعرض اثنين بسعر واحد.
تخيّل مخبزًا يقدّم عرضًا في العطلة، حيث يمكنك شراء قطعتين من الكعك بسعر قطعة واحدة ("two-fer one!"). فتأخذ العرض و(بكرم بالغ) تقرّر أن تعطي الكعكة الإضافية لشخص آخر في الطابور.
مهمتك هي أن تحدد ما ستقوله وأنت تعطي الكعكة الإضافية.
إذا كنت تعرف اسم الشخص (مثلًا إذا كان اسمه Do-yun)، فستقول:
One for Do-yun, one for me.
وإذا لم تكن تعرف اسم الشخص، فستقول you بدلًا من ذلك.
One for you, one for me.
إليك بعض الأمثلة:
| الاسم | الحوار |
|---|---|
| Alice | One for Alice, one for me. |
| Bohdan | One for Bohdan, one for me. |
| One for you, one for me. | |
| Zaphod | One for Zaphod, one for me. |
تدعم Odin الوسائط الافتراضية. الوسائط الافتراضية ميزة مفيدة تتيح استدعاء إجراء بمجموعات مختلفة من المعاملات في حالات الاستخدام التي تحتاج فيها إلى واجهات API مترابطة لكنها مختلفة.
بدون الوسائط الافتراضية، قد ينتهي بك الأمر إلى تضخم عدد الإجراءات التي تحتاجها واجهة API لديك. أما اللغات التي لا تدعم الوسائط الافتراضية، مثل Java، فتعتمد على التحميل الزائد للطرق للحصول على الأثر نفسه (مع كتابة كود أكثر)، أو عليها أن توفر إجراءات بمجموعة كبيرة من الوسائط.
لنأخذ مثالًا على إجراء greeting نريد فيه أن نحدد اللغة، وما إذا كان الاسم بحروف كبيرة، وما إذا كان ينبغي إضافة علامة تعجب في نهاية التحية.
بعد بعض التحليل، وجدنا أن أكبر مجموعة من المستخدمين تحدد الإنجليزية كلغة، ولا تكتب الاسم بحروف كبيرة، ولا تريد علامة تعجب في النهاية، بينما تضيف ثاني أكبر مجموعة علامة تعجب في نهاية التحية.
يمكننا إنشاء إجراء واحد بكل الوسائط:
greeting :: proc(name: string, language: Language, do_uppercase: bool, add_exclamation: bool) {
...
}
وهذا سيجبر جميع المستخدمين على قراءة التوثيق الخاص بكل الوسائط وتعبئتها دائمًا.
وبدون الوسائط الافتراضية، يمكننا أيضًا تعريف عدة إجراءات بمجموعات مختلفة من المعاملات:
greeting_common :: proc(name: string) {...}
greeting_with_exclamation :: proc(name: string) {...}
greeting_general :: proc(name: string, language: Language, do_uppercase: bool, add_exclamation: bool) {...}
// Odin supports overloading but it has to be explicitly defined
greeting :: proc {
greeting_common,
greeting_with_exclamation,
greeting_general,
}
إذا كانت لغتك تدعم الوسائط الافتراضية، كما تفعل Odin، فيمكنك ببساطة أن تزوّد الوسائط الأقل استخدامًا بقيم افتراضية معقولة. ويمكن للمستدعين تخطي الوسائط الافتراضية، فيستخدم الإجراء القيم الافتراضية المزوَّدة، أو تجاوزها.
greeting :: proc(name: string, language: Language = Language.English, do_uppercase : bool = false, add_exclamation: bool = false) {...}
// Note: because Odin supports type inference, we can simplify the interface.
greeting :: proc(name: string, language:= Language.English, do_uppercase := false, add_exclamation:= false) {...}
يمكن استدعاء الإجراء مع ترك كل الوسائط على قيمها الافتراضية:
greeting("John Doe")
أما الوسائط المهمة للمستدعي فيمكن تجاوزها:
greeting("John Doe", Language.Spanish)
إذا كانت الوسائط التي تحتاجها مرتبة بحسب موقعها، كما في المثال أعلاه، فلا حاجة إلى تسميتها كما في المثال أعلاه، أما إذا احتجت إلى تخطي بعضها، فعليك تسمية الوسائط التي تأتي بعد أول وسيط تخطيته.
greeting("John Doe", add_exclamation=true)
في هذا التمرين ستُنفّذ إجراءً مهمته تخصيص السلسلة النصية التي يُرجعها. أما إلغاء تخصيص السلسلة النصية فمسؤولية المستدعي.
// The procedure will be called like that:
str := two_fer("Alice")
// ...
// and eventually the caller will delete the string
delete(str)
قد يهمك أيضًا الاطلاع على توثيق Odin الرسمي حول الوسائط الافتراضية والوسائط المسماة.
سجّل في Exercism لتتعلّم وتتقن Odin عبر 73 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.