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 obtiene el último elemento de una lista, necesitas para acceder al código de lista varias veces:
// Incorrect block-code generator.
javascriptGenerator.forBlock['last_element'] = function(block, generator) {
const listCode = generator.valueToCode(block, 'LIST', Order.MEMBER);
// listCode gets referenced twice.
const code = `${listCode}[${listCode}.length - 1]`;
return [code, Order.MEMBER];
}
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:
randomList()[randomList().length - 1]
El uso de funciones de utilidad te permite asegurarte de que los bloques internos el código solo es se evalúe una vez.
Funciones de utilidad
Una función de utilidad es una función definida por el desarrollador incluida como parte del cadena de código generada. Puedes usarlos para asegurarte de que el código solo se evalúa una vez y, luego, se puede hacer referencia al valor varias veces.
import {javascriptGenerator, Order} from 'blockly/javascript';
// Correct block-code generator.
javascriptGenerator.forBlock['last_element'] = function(block, generator) {
const listCode = generator.valueToCode(block, 'LIST', Order.NONE);
const functionName = generator.provideFunction_(
'list_lastElement',
[
`function ${generator.FUNCTION_NAME_PLACEHOLDER_}(list) {`,
` return list[list.length - 1];`,
`}`
]
);
// listCode only gets evaluated once.
const code = `${functionName}(${listCode})`;
return [code, Order.FUNCTION_CALL];
}
Proporciona la función
Puedes definir funciones de utilidad dentro de generadores de código de bloque con
provideFunction_
Toma el nombre que deseas para tu función de utilidad y
un array de cadenas de código que define lo que hace la función. Devuelve el
nombre resultante de tu función de utilidad, después (posiblemente) de modificarla para que no
entran en conflicto con las funciones
definidas por el usuario.
provideFunction_
también anula los duplicados de las definiciones de funciones de utilidad, de modo que cada
función de utilidad solo existe una vez, incluso si el tipo de bloque que la define existe
varias veces.
Actualizar prioridades
Cuando defines una función de utilidad, también debes actualizar las precedencias (que definen cómo se insertan los paréntesis) incluidos en la de código de bloque.
La prioridad siempre se basa en la cadena de código que muestra el código de bloque.
generador. No le interesan los operadores dentro de las funciones de utilidad. En la
ejemplo anterior, la llamada valueToCode
se cambió a Order.NONE
y el
se cambió la tupla de retorno a Order.FUNCTION_CALL
.