L'instruction bloque la mise en cache des arguments

Parfois, votre générateur de code de bloc doit référencer le code de son propre de bloquer plusieurs fois.

Par exemple, si l'un de vos blocs affiche le dernier élément d'une liste, besoin d'accéder au code de la liste plusieurs fois:

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

Mais cela peut poser des problèmes si la valeur résultante du code du bloc interne est incohérente ou elle a des effets secondaires. Par exemple, si le code interne est en fait un appel de fonction, ce code particulier peut se retrouver avec une condition hors plage:

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

L'attribution de variables temporaires vous permet de vous assurer que le code du bloc interne est n'est évaluée qu'une seule fois.

Variables temporaires

Une variable temporaire stocke la valeur de la chaîne de code d'un bloc interne afin que le code n'est évalué qu'une seule fois, et la valeur peut alors être référencée plusieurs fois.

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

L'appel getDistinctName utilise le nom de variable souhaité et renvoie une qui n'entre pas en conflit avec une variable définie par l'utilisateur.

Réduire le code redondant

L'inconvénient des variables temporaires est que, si le code du bloc interne est une valeur et non une fonction ou une expression, vous obtenez du code redondant:

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

Pour produire un code plus propre, vous pouvez vérifier si le code du bloc interne est une valeur, et n'incluez que la variable temporaire si ce n'est pas le cas.

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