ذخیره آرگومان بلوک ارزش

گاهی اوقات مولد کد بلوک شما نیاز دارد چندین بار به کد بلوک داخلی خود ارجاع دهد.

به عنوان مثال، اگر بلوکی دارید که آخرین عنصر یک لیست را دریافت می کند، باید چندین بار به کد لیست دسترسی داشته باشید:

// 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 تغییر یافت.