January 15, 2006

... Rest :שאר הארגומנטים, או

הנה עוד פיצ'ר חמוד לניהול ארגומנטים בפונקציות (או מתודות, אם תרצו).
בעבר כאשר לא ידענו מה יהיה מספר הארגומנטים שנקבל לפונקציה, היינו משתמשים במאפיין arguments שלה, בד"כ בצורה הבאה:



function doSomething ():Void {
for (var i in arguments) {
trace (i + " = " + arguments[i])
}
}
doSomething ("Matti", 1, [1,2,3], true)

// Displays:
// 3 = true
// 2 = 1,2,3
// 1 = 1
// 0 = Matti


הבעיה עלתה כאשר ידענו שהפונקציה אמורה לקבל לפחות 2 פרמטרים (למשל) והשאר הם פרמטרים אופציונאלים, שאם מקבלים אותם אז יודעים מה לעשות איתם לפי ה-type שלהם, אך אם הם אינם, מתעלמים מכך. הדבר היה גורר אותנו לבצע כל מיני שאילתות על ה-type של הפרמטר, ואיך קוראים לו וכיו"ב... לא נעים.
as3 מציעה לנו פיתרון לא רע בכלל שנקרא: "args …". args גם יכול להיות כל מחרוזת שתבחרו, למשל rest או chuck.
כך ממש, עם שלוש-הנקודות – זהו פרמטר אשר למעשה אומר:"את כל השאר חוץ ממה שמוגדר". אם למשל יש לנו פונקציה שאמורה לקבל 2 פרמטרים תמיד, אחד מהם יהיה מחרוזת והשני מערך ובנוסף לכך נרצה לקבל את שאר הארגומנטים אם יש ולטפל בהם באופן אחר, אזי נשתמש בפרמטר " rest ...". הצורה הבסיסית היא כזו:



protected function someFunction (first_str:String, second_array:Array, ... rest)


פרמטר ראשון הוא מחרוזת, השני מערך והשאר יכולים להיות "עוף בסומסום" אם היה type שכזה (וחבל שאין, זה היה יכול לשפר את התפריט שלנו).
ואיך זה עובד? או!
מה שקורה הוא, שאם אני אחסיר אחד מהפרמטרים שחייבים להיות, הקומפיילר יצעק. אם אשים פרמטרים שאינם מתאימים ל-type המוגדר בפונקציה, הקומפיילר יזעק. מה שפחות או יותר סוגר לנו את אפשרויות ה"עשה מה בראש שלך". ברגע שסיפקנו שני משתנים המתאימים להגדרות ה-type שבפונקציה, כל השאר יכנסו תחת ה-rest.
הנה דוגמה קלה:



public function restExample() {
someFunction ("Matti", [0, 1, 2], 1, 2, 3, 4);
// Displays: 1, 2, 3, 4
someFunction ([0, 1, 2], 1, 2, 3, 4);
// Displays: CompileTime Error
someFunction ("Matti", 1, 2, 3, 4);
// Displays: CompileTime Error
}
protected function someFunction (_str:String, _array:Array, ... rest):Void {
for (var i:Object in rest) {
trace (rest[i])
}
}


חמוד, לא?

2 comments:

IAP said...

וכשיש צורך בארגומנט אופציונאלי עם ברירת מחדל, יש איזו שיטת קיצור נחמדה, או שחוזרים לבדיקה האם שווה הדבר לundefined.

(אגב, לא העברית מציקה, הקוד)

FlashMattic said...

כן, אני יודע.
אני סומך על זה שמי שבאמת רוצה לחקור אותו יעשה copy paste חפוז.