A veces, el generador de código de bloque necesita hacer referencia al código de su varias veces.
Por ejemplo, si tienes un bloque que imprime el último elemento de una lista, puedes Necesitas acceder al código de lista varias veces:
// 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`;
}
Pero esto puede causar problemas si el valor resultante del código del bloque interno es incoherentes o tienen efectos secundarios. Por ejemplo, si el código interno una llamada a función, este código específico puede terminar con una condición fuera de rango:
print(randomList()[randomList().length - 1]);
Al asignar variables temporales, te aseguras de que el código del bloque interno solo se evalúa una vez.
Variables temporales
Una variable temporal almacena el valor de la cadena de código de un bloque interno El código solo se evalúa una vez y, luego, se puede hacer referencia al valor varios veces.
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`;
}
La llamada getDistinctName
toma el nombre de la variable que deseas y muestra un
que no entre en conflicto con ninguna variable definida por el usuario.
Reduce el código redundante
La desventaja de las variables temporales es que si el código del bloque interno es un valor y no una función o expresión, obtendrás un código redundante:
// Assigning to temp_list is unnecessary.
var temp_list = foo;
print(temp_list[temp_list.length - 1]);
Para producir un código más limpio, puedes comprobar si el código del bloque interno es un valor. solo incluir la variable temporal si no lo es.
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`;
}