값 블록 인수 캐싱

블록 코드 생성기가 내부 여러 번 차단할 수 있습니다.

예를 들어 목록의 마지막 요소를 가져오는 블록이 있는 경우 를 사용하여 목록 코드에 여러 번 액세스합니다.

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

하지만 내부 블록 코드의 결과 값이 부작용이 있을 수 있습니다 예를 들어 내부 코드가 실제로 함수를 호출하면 이 특정 코드는 범위를 벗어난 상태가 될 수 있습니다.

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

유틸리티 함수를 사용하면 내부 블록의 코드가 한 번 평가됩니다.

유틸리티 함수

유틸리티 함수는 생성된 코드 문자열을 반환합니다. 이를 사용하여 내부 블록 코드가 한 번만 평가되면 값이 여러 번 참조될 수 있습니다.

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

함수 제공

다음 명령어를 사용하여 블록 코드 생성기 내에서 유틸리티 함수를 정의할 수 있습니다. provideFunction_ 유틸리티 함수에 원하는 이름을 가져오고 함수의 기능을 정의하는 코드 문자열의 배열입니다. 이 함수는 유틸리티 함수의 결과 이름 (가능한 경우)을 사용자 정의 함수와 충돌하지 않습니다.

provideFunction_는 유틸리티 함수 정의도 중복 삭제하므로 각 유틸리티 유틸리티 함수는 함수를 정의하는 블록 유형이 존재하더라도 한 번만 존재합니다. 여러 번 반복해야 할 수도 있습니다.

우선순위 업데이트

유틸리티 함수를 정의할 때 우선순위도 업데이트해야 합니다. (괄호 삽입 방법을 정의)는 블록 코드 생성기를 사용합니다.

우선순위는 항상 블록 코드에서 반환한 코드 문자열을 살펴보겠습니다 유틸리티 함수 내의 연산자는 신경 쓰지 않습니다. 따라서 이전 예에서는 valueToCode 호출이 Order.NONE로 변경되었고 반환 튜플이 Order.FUNCTION_CALL로 변경되었습니다.