متغیرها

متغیرها یک مفهوم مهم برنامه‌نویسی هستند. Blockly از زبان‌های با نوع پویا مانند پایتون و جاوا اسکریپت پشتیبانی می‌کند و با کمی کار اضافی، می‌توانید اطلاعاتی را برای پشتیبانی از زبان‌های با نوع قوی (یا زبان‌های با نوع ایستا) مانند جاوا یا C اضافه کنید.

برای اطلاعات بیشتر در مورد زبان‌های نوع‌بندی پویا در مقابل ایستا، به مقدمه‌ای بر انواع داده: ایستا، پویا، قوی و ضعیف مراجعه کنید.

Blockly فیلدهای متغیر را ارائه می‌دهد که جعبه‌های کشویی پویایی هستند که نام متغیرهایی را که کاربر ارائه کرده است نشان می‌دهند. در زیر مثالی از یکی از آنها آمده است.

یک فیلد متغیر با یک منوی کشویی برای انتخاب یک متغیر، تغییر نام متغیر فعلی یا حذف متغیر فعلی.

به طور پیش‌فرض، Blockly اجازه می‌دهد هر نوعی به یک متغیر اختصاص داده شود و تمام مولدهای ارائه شده توسط Blockly برای زبان‌های تایپ‌شده پویا هستند. اگر به جای آن از یک زبان تایپ‌شده استفاده می‌کنید، می‌توانید Blockly را برای پشتیبانی از آن با انجام موارد زیر پیکربندی کنید:

بلوک‌های متغیر بدون نوع

اساسی‌ترین بلوک‌ها برای دسترسی و دستکاری یک متغیر، بلوک‌های getter و setter هستند. بیایید بلوک‌های getter و setter که Blockly ارائه می‌دهد را بررسی کنیم.

جی‌سون

// Block for variable getter.
{
  "type": "variables_get",
  "message0": "%1",
  "args0": [
    {    // Beginning of the field variable dropdown
      "type": "field_variable",
      "name": "VAR",    // Static name of the field
      "variable": "%{BKY_VARIABLES_DEFAULT_NAME}"    // Given at runtime
    }    // End of the field variable dropdown
  ],
  "output": null,    // Null means the return value can be of any type
  ...
},

// Block for variable setter.
{
  "type": "variables_set",
  "message0": "%{BKY_VARIABLES_SET}",
  "args0": [
    {
      "type": "field_variable",
      "name": "VAR",
      "variable": "%{BKY_VARIABLES_DEFAULT_NAME}"
    },
    {
      "type": "input_value",    // This expects an input of any type
      "name": "VALUE"
    }
  ],
  ...
}

جاوا اسکریپت

// Block for variable getter.
Blockly.Blocks['variables_get'] = {
  init: function() {
    this.appendDummyInput()
      .appendField(new Blockly.FieldVariable("VAR_NAME"), "FIELD_NAME");
    this.setOutput(true, null);
    ...
  }
};

// Block for variable setter.
Blockly.Blocks['variables_set'] = {
  init: function() {
    this.appendValueInput("NAME")
        .setCheck(null)
        .appendField("set")
        .appendField(new Blockly.FieldVariable("VAR_NAME"), "FIELD_NAME")
        .appendField("to");
    this.setOutput(true, null);
    ...
  }
};

این دو بلوک زیر را ایجاد می‌کند:

بلوک‌های دریافت‌کننده و تنظیم‌کننده برای متغیر `foo`.

نکته‌ی مهمی که باید به آن توجه کرد این است که با تنظیم "خروجی" متغیر getter روی null، مقدار برگشتی می‌تواند از هر نوعی باشد. همچنین، توجه داشته باشید که ورودی متغیر setter هیچ بررسی‌ای را مشخص نمی‌کند. در نتیجه، متغیر می‌تواند روی هر نوع مقداری تنظیم شود.

بلوک‌های متغیر نوع‌گذاری شده

شما می‌توانید getterها و setterهایی اضافه کنید که بررسی نوع را اعمال می‌کنند. برای مثال، اگر متغیری از نوع "Panda" ایجاد کرده‌اید، تعاریف زیر یک getter و setter با انواع مناسب ایجاد می‌کنند.

جی‌سون

// Block for Panda variable getter.
{
  "type": "variables_get_panda",
  "message0": "%1",
  "args0": [
    {
      "type": "field_variable",
      "name": "VAR",
      "variable": "%{BKY_VARIABLES_DEFAULT_NAME}",
      "variableTypes": ["Panda"],    // Specifies what types to put in the dropdown
      "defaultType": "Panda"
    }
  ],
  "output": "Panda",    // Returns a value of "Panda"
  ...
},

 // Block for Panda variable setter.
{
  "type": "variables_set_panda",
  "message0": "%{BKY_VARIABLES_SET}",
  "args0": [
    {
      "type": "field_variable",
      "name": "VAR",
      "variable": "%{BKY_VARIABLES_DEFAULT_NAME}",
      "variableTypes": ["Panda"],
      "defaultType": "Panda"
    },
    {
      "type": "input_value",
      "name": "VALUE",
      "check": "Panda"    // Checks that the input value is of type "Panda"
    }
  ],
  "previousStatement": null,
  "nextStatement": null,
  ...
}

جاوا اسکریپت

// Block for Panda variable getter.
Blockly.Blocks['variables_get_panda'] = {
  init: function() {
    this.appendDummyInput()
      .appendField(new Blockly.FieldVariable(
          "VAR_NAME", ['Panda'], 'Panda'), "FIELD_NAME");
    this.setOutput(true, 'Panda');
    ...
  }
};

// Block for Panda variable setter.
Blockly.Blocks['variables_set_panda'] = {
  init: function() {
    this.appendValueInput("NAME")
        .setCheck('Panda')
        .appendField("set")
        .appendField(new Blockly.FieldVariable(
            "VAR_NAME", null, ['Panda'], 'Panda'), "FIELD_NAME")
        .appendField("to");
        this.setPreviousStatement(true, null);
        this.setNextStatement(true, null);
    ...
  }
};

این دو نوع بلوک ایجاد می‌کند، یک getter و یک setter. منوی کشویی آنها فقط متغیرهایی از نوع "Panda" را نمایش می‌دهد. ورودی‌ها و خروجی‌های آنها فقط اتصالاتی با نوع "Panda" را می‌پذیرند. defaultType فیلد باید روی یکی از مقادیر موجود در آرایه variableTypes تنظیم شود. عدم تنظیم defaultType هنگام ارائه آرایه variableTypes باعث ایجاد خطا می‌شود.

به طور پیش‌فرض هیچ نشانگر بصری برای اطلاع کاربر از نوع مورد استفاده وجود ندارد. یک راه آسان برای تمایز انواع متغیرها، رنگ است.

اضافه کردن متغیرها به جعبه ابزار

برای اینکه این نوع متغیر جدید برای کاربرانتان مفید باشد، باید روشی برای ایجاد و استفاده از متغیرهای جدید اضافه کنید.

اگر از قبل دسته‌بندی پویای جدیدی برای متغیرها ندارید، آن را ایجاد کنید.

یک دسته‌بندی باز با نام «متغیرها» که حاوی دکمه‌ی «ایجاد متغیر» است.

getterها و setterهای جدید خود را به این دسته اضافه کنید.

همان دسته‌بندی بعد از متغیرهای `foo` و `bar` ایجاد شده‌اند. این دسته‌بندی شامل یک دکمه‌ی "ایجاد متغیر"، بلوک‌های set-variable-to و change-variable-by و بلوک‌های getter است.

دکمه متغیر ایجاد کنید

در مرحله بعد، کاربر شما به روشی برای ایجاد متغیرها نیاز دارد. ساده‌ترین راه استفاده از دکمه "ایجاد متغیر" است.

هنگام ایجاد دکمه، فراخوانی برگشتی را انجام دهید

Blockly.Variables.createVariableButtonHandler(button.getTargetWorkspace(), null, 'panda');

و یک متغیر با نوع "Panda" ایجاد خواهد شد!

ساده‌ترین راه برای اینکه به کاربران اجازه دهید متغیرهایی از چندین نوع ایجاد کنند، این است که برای هر نوع، یک دکمه «ایجاد» داشته باشید (مثلاً ایجاد متغیر رشته‌ای، ایجاد متغیر عددی، ایجاد متغیر پاندا).

اگر بیش از دو یا سه نوع متغیر دارید، ممکن است به سرعت با دکمه‌های زیادی مواجه شوید. در این صورت، استفاده از @blockly/plugin-typed-variable-modal را برای نمایش یک پنجره بازشو در نظر بگیرید که کاربران می‌توانند نوع متغیر مورد نظر خود را از آن انتخاب کنند.

تعریف ژنراتورها

در نهایت، شما نیاز به تعریف مولدهای کد بلوک برای بلوک‌های متغیر جدید خود خواهید داشت. همچنین می‌توانید مستقیماً با Workspace.getVariableMap().getAllVariables() به لیست متغیرها دسترسی پیدا کنید تا همه متغیرها از همه نوع را دریافت کنید یا Workspace.getVariableMap().getVariablesOfType() برای دریافت همه متغیرهای یک نوع خاص دریافت کنید.