Memorizzazione nella cache degli argomenti del blocco di valori

A volte il generatore di codici a blocchi deve fare riferimento più volte al codice del suo blocco interno.

Ad esempio, se hai un blocco che riceve l'ultimo elemento di un elenco, devi accedere più volte al codice dell'elenco:

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

Tuttavia, questo può causare problemi se il valore risultante del codice del blocco interno non è coerente o ha effetti collaterali. Ad esempio, se il codice interno è in realtà una chiamata di funzione, questo particolare codice può finire con una condizione fuori intervallo:

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

L'uso delle funzioni di utilità consente di assicurarsi che il codice dei blocchi interni venga valutato una sola volta.

Funzioni di utilità

Una funzione di utilità è una funzione definita dallo sviluppatore inclusa nella stringa di codice generata. Puoi utilizzarli per assicurarti che il codice del blocco interno venga valutato una sola volta e che quindi sia possibile fare riferimento più volte al valore.

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

Fornisci la funzione

Puoi definire le funzioni di utilità all'interno dei generatori di codici a blocchi utilizzando provideFunction_. Prende il nome che vuoi usare per la funzione di utilità e un array di stringhe di codice che definiscono la funzione della funzione. Restituisce il nome risultante della funzione di utilità, dopo averlo modificato (possibilmente) in modo che non sia in conflitto con le funzioni definite dall'utente.

provideFunction_ deduplica anche le definizioni delle funzioni di utilità, in modo che ogni funzione esista una sola volta, anche se il tipo di blocco che la definisce esiste più volte.

Aggiorna la precedenza

Quando definisci una funzione di utilità, devi anche aggiornare le precedenza (che definiscono la modalità di inserimento delle parentesi) incluse nel generatore di codici a blocchi.

La precedenza si basa sempre sulla stringa di codice restituita dal generatore di codici a blocchi. Non importa gli operatori all'interno delle funzioni di utilità. Nell'esempio precedente, la chiamata a valueToCode è stata modificata in Order.NONE e la tupla di ritorno in Order.FUNCTION_CALL.