يحظر العبارة التخزين المؤقت لوسيطات التخزين المؤقت

في بعض الأحيان، يحتاج منشئ رمز الكتلة إلى الإشارة إلى رمز الكتلة الداخلية عدة مرات.

على سبيل المثال، إذا كان لديك كتلة تطبع العنصر الأخير في القائمة، فستحتاج إلى الوصول إلى كود القائمة عدة مرات:

// 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`;
}