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

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

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

// 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_ גם משנה את ההגדרות של פונקציות הכלי, כך שכל אחת פונקציית השירות קיימת רק פעם אחת, גם אם סוג הבלוק שמגדיר אותה קיים. כמה פעמים.

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

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

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