في بعض الأحيان، يحتاج منشئ رمز الحظر إلى الإشارة إلى الرمز الخاص به الحظر عدة مرات.
على سبيل المثال، إذا كان لديك كتلة تطبع العنصر الأخير من القائمة، فيجب الوصول إلى رمز القائمة عدة مرات:
// 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`;
}