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