Buforowanie argumentów bloku wartości

Czasami generator kodu blokowego musi odwoływać się do kodu swojego wewnętrznego kodu zablokować wiele razy.

Na przykład jeśli masz blok, który pobiera ostatni element listy, musisz aby wielokrotnie wyświetlić kod listy:

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

Może to jednak powodować problemy, jeśli wartość wynikowa kodu wewnętrznego bloku to niespójne lub mają skutki uboczne. Jeśli na przykład wewnętrzny kod to wywołaniem funkcji, ten konkretny kod może skończyć się warunkiem „poza zakresem”:

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

Dzięki funkcjom użytkowym masz pewność, że wewnętrzne bryły kod to tylko tylko raz.

Funkcje użytkowe

Funkcja użytkowa to zdefiniowana przez programistę funkcja zawarta w . Można ich użyć, aby sprawdzić, czy kod oceniono tylko raz, a wartość może być odwołana kilka razy.

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

Podaj funkcję

Funkcje użytkowe możesz zdefiniować w generatorach kodu blokowego za pomocą provideFunction_ Przyjmuje odpowiednią nazwę funkcji użytkowej. tablicę ciągów kodu definiujących działanie funkcji. Zwraca ono wynikowa nazwa funkcji użytkowej po zmodyfikowaniu jej (prawdopodobnie) tak, w przypadku wystąpienia konfliktu z funkcjami zdefiniowanymi przez użytkownika.

Funkcja provideFunction_ deduplikuje też definicje funkcji użytkowych, tak aby każda z nich funkcja użytkowa występuje tylko raz, nawet jeśli istnieje typ bloku, który ją definiuje; wiele razy.

Zaktualizuj priorytety

Gdy definiujesz funkcję użytkową, musisz też zaktualizować priorytety (które określają sposób wstawiania nawiasów wstawionych w elemencie z generatorem kodów blokowych.

Pierwszeństwo jest zawsze określane na podstawie ciągu kodu zwracanego przez kod blokowy. generatora. Operatory w funkcjach użytkowych nie mają znaczenia. W przypadku w poprzednim przykładzie wywołanie valueToCode zostało zmienione na Order.NONE, a krotka zwrotu została zmieniona na Order.FUNCTION_CALL.