שמירה במטמון של ארגומנט בלוק ערך

לפעמים מחולל קוד הבלוקים צריך להפנות לקוד של הבלוק הפנימי שלו מספר פעמים.

לדוגמה, אם יש בלוק שמקבל את הרכיב האחרון ברשימה, עליכם להיכנס לקוד הרשימה כמה פעמים:

// Incorrect block-code generator.
javascriptGenerator.forBlock['last_element'] = function(block, generator) {
  const listCode = generator.valueToCode(block, 'LIST', Order.MEMBER);

  // listCode gets referenced twice.
  const code = `${listCode}[${listCode}.length - 1]`;

  return [code, Order.MEMBER];
}

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

randomList()[randomList().length - 1]

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

פונקציות שירות

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

import {javascriptGenerator, Order} from 'blockly/javascript';

// Correct block-code generator.
javascriptGenerator.forBlock['last_element'] = function(block, generator) {
  const listCode = generator.valueToCode(block, 'LIST', Order.NONE);
  const functionName = generator.provideFunction_(
      'list_lastElement',
      [
        `function ${generator.FUNCTION_NAME_PLACEHOLDER_}(list) {`,
        `  return list[list.length - 1];`,
        `}`
      ]
  );

  // listCode only gets evaluated once.
  const code = `${functionName}(${listCode})`;
  return [code, Order.FUNCTION_CALL];
}

מספקים את הפונקציה

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

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

עדכון הקדימות

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

התעדוף תמיד מבוסס על מחרוזת הקוד שמוחזרת ממחולל קוד הבלוק. לא חשוב לה אופרטורים בתוך פונקציות כלי עזר. כך שבדוגמה הקודמת, הקריאה valueToCode שונתה ל-Order.NONE וה-tuple של ההחזרה השתנה ל-Order.FUNCTION_CALL.