משתנים

משתנים הם מושג חשוב בתכנות. ‫Blockly תומכת בשפות עם הקלדה דינמית כמו Python ו-JavaScript, ואפשר להוסיף מידע כדי לתמוך בשפות עם הקלדה חזקה (או בשפות עם הקלדה סטטית) כמו Java או C.

מידע נוסף על שפות עם הקלדה דינמית לעומת שפות עם הקלדה סטטית זמין במאמר מבוא לסוגי נתונים: סטטיים, דינמיים, חזקים וחלשים.

‫Blockly מספקת שדות משתנים שהם תיבות נפתחות דינמיות שמציגות את שמות המשתנים שהמשתמש סיפק. למטה מופיעה דוגמה.

שדה משתנה עם תפריט נפתח לבחירת משתנה, לשינוי השם של המשתנה הנוכחי או למחיקת המשתנה הנוכחי.

כברירת מחדל, Blockly מאפשרת להקצות לכל משתנה כל סוג, וכל הגנרטורים ש-Blockly מספקת הם לשפות עם הקלדה דינמית. אם אתם משתמשים בשפה עם הקלדה, אתם יכולים להגדיר את Blockly כך שתהיה תמיכה בשפה הזו באופן הבא:

בלוקים של משתנים ללא סוג

הבלוקים הבסיסיים ביותר לגישה למשתנה ולשינוי שלו הם בלוקים מסוג getter ו-setter. נבחן את בלוקי ה-getter וה-setter ש-Blockly מספקת.

JSON

// 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"
    }
  ],
  ...
}

JavaScript

// 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);
    ...
  }
};

כך נוצרים שני הבלוקים הבאים:

בלוקים של getter ו-setter למשתנה `foo`.

פרט חשוב שכדאי לשים לב אליו הוא שאם מגדירים את ה'פלט' של הפונקציה להחזרת משתנה כ-null, ערך ההחזרה יכול להיות מכל סוג. בנוסף, שימו לב שאין בדיקות שצוינו בקלט של רכיב הגדרת המשתנה. כתוצאה מכך, אפשר להגדיר את המשתנה לכל סוג של ערך.

בלוקים של משתנים מוקלדים

אפשר להוסיף getters ו-setters שמבצעים בדיקת סוג. לדוגמה, אם יצרתם משתנה מסוג "Panda", ההגדרות הבאות יוצרות getter ו-setter עם הסוגים המתאימים.

JSON

// 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,
  ...
}

JavaScript

// 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, תופיע שגיאה.

כברירת מחדל, אין אינדיקטור חזותי שמציין למשתמש באיזה סוג הוא משתמש. דרך קלה להבחין בין סוגי משתנים היא לפי הצבע.

הוספת משתנים לכלי העריכה

כדי שהמשתמשים יוכלו להשתמש בסוג החדש הזה של משתנה, צריך להוסיף דרך ליצור את המשתנים החדשים ולהשתמש בהם.

אם עדיין אין לכם קטגוריה דינמית למשתנים, יוצרים אחת חדשה.

קטגוריה פתוחה בשם 'משתנים' שמכילה לחצן 'יצירת משתנה'.

מוסיפים את ה-getters וה-setters החדשים לקטגוריה.

אותה קטגוריה אחרי שנוצרו המשתנים 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() כדי לקבל את כל המשתנים מסוג מסוים.