Pernyataan memblokir argumen caching

Terkadang generator kode blok Anda perlu merujuk kode blok dalamnya beberapa kali.

Misalnya, jika Anda memiliki blok yang mencetak elemen terakhir dari suatu daftar, Anda harus mengakses kode daftar beberapa kali:

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

Namun, hal ini dapat menyebabkan masalah jika nilai yang dihasilkan dari kode blok dalam tidak konsisten, atau memiliki efek samping. Misalnya, jika kode dalam sebenarnya adalah panggilan fungsi, kode khusus ini dapat berakhir dengan kondisi di luar rentang:

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

Dengan menetapkan variabel sementara, Anda dapat memastikan bahwa kode blok dalam hanya dievaluasi sekali.

Variabel sementara

Variabel sementara menyimpan nilai string kode blok dalam sehingga kode hanya dievaluasi satu kali, lalu nilai dapat direferensikan beberapa kali.

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

Panggilan getDistinctName menggunakan nama variabel yang Anda inginkan, dan menampilkan nama yang tidak bertentangan dengan variabel buatan pengguna.

Mengurangi kode yang berlebihan

Kelemahan dari variabel sementara adalah jika kode blok dalam adalah nilai, bukan fungsi atau ekspresi, Anda akan mendapatkan kode yang redundan:

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

Untuk menghasilkan kode yang lebih sederhana, Anda dapat memeriksa apakah kode blok dalam merupakan sebuah nilai, dan hanya menyertakan variabel sementara jika bukan.

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