ההצהרה חוסמת ארגומנטים של שמירה במטמון

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

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

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

  // listCode gets referenced twice.
  return `print(${listCode}[${listCode}.length - 1]);\n`;
}

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

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

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

משתנים זמניים

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

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

// Correct block-code generator.
javascriptGenerator.forBlock['print_last_element'] = function(block, generator) {
  const listCode = generator.valueToCode(block, 'LIST', Order.MEMBER);
  const listVar = generator.nameDB_.getDistinctName(
      'temp_list', Blockly.names.NameType.VARIABLE);

  // listCode only gets evaluated once.
  const code = `var ${listVar} = ${listCode};\n`;
  return `print(${listVar}[${listVar}.length - 1]);\n`;
}

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

הפחתת קוד מיותר

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

// Assigning to temp_list is unnecessary.
var temp_list = foo;
print(temp_list[temp_list.length - 1]);

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

if (listCode.match(/^\w+$/)) {
  const code = `print(${listCode}[${listCode}.length - 1]);\n`;
} else {
  const listVar = generator.nameDB_.getDistinctName(
      'temp_list', Blockly.names.NameType.VARIABLE);
  const code = `var ${listVar} = ${listCode};\n`;
  code += `print(${listVar}[${listVar}.length - 1]);\n`;
}