Zmienne

Zmienne to ważne pojęcie w programowaniu. Blockly obsługuje języki o dynamicznym typowaniu, takie jak Python i JavaScript. Po wykonaniu kilku dodatkowych czynności możesz dodać informacje, które będą obsługiwać języki o silnym typowaniu (lub języki o typowaniu statycznym), takie jak Java czy C.

Więcej informacji o językach z dynamicznym i statycznym typowaniem znajdziesz w artykule Introduction to Data Types: Static, Dynamic, Strong & Weak (w języku angielskim).

Blockly udostępnia pola zmiennych, które są dynamicznymi polami wyboru wyświetlającymi nazwy zmiennych podane przez użytkownika. Poniżej znajdziesz przykład.

Pole zmiennej z menu, w którym możesz wybrać zmienną, zmienić jej nazwę lub ją usunąć.

Domyślnie Blockly umożliwia przypisanie do zmiennej dowolnego typu, a wszystkie generatory dostarczane przez Blockly są przeznaczone dla języków o dynamicznym typowaniu. Jeśli używasz języka typowanego, możesz skonfigurować Blockly tak, aby go obsługiwał. W tym celu wykonaj te czynności:

Bloki zmiennych bez typu

Najbardziej podstawowe bloki służące do uzyskiwania dostępu do zmiennej i manipulowania nią to bloki pobierania i ustawiania. Przyjrzyjmy się blokom pobierania i ustawiania, które udostępnia 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);
    ...
  }
};

Spowoduje to utworzenie tych 2 bloków:

Bloki pobierania i ustawiania zmiennej `foo`.

Ważne jest, aby zauważyć, że ustawiając „dane wyjściowe” funkcji pobierającej zmienną na wartość null, wartość zwracana może być dowolnego typu. Zwróć też uwagę, że dane wejściowe funkcji ustawiającej zmienną nie określają żadnych weryfikacji. Dzięki temu zmienna może przyjmować dowolny typ wartości.

Bloki zmiennych z określonym typem

Możesz dodać funkcje pobierające i ustawiające, które wymuszają sprawdzanie typu. Jeśli np. utworzysz zmienną typu "Panda", poniższe definicje utworzą funkcję pobierającą i ustawiającą z odpowiednimi typami.

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

Spowoduje to utworzenie 2 rodzajów bloków: pobierającego i ustawiającego. Menu tych elementów wyświetlają tylko zmienne typu "Panda". Ich dane wejściowe i wyjściowe akceptują tylko połączenia typu "Panda". Wartość pola defaultType musi być ustawiona na jedną z wartości w tablicy variableTypes. Jeśli podczas podawania tablicy variableTypes nie ustawisz parametru defaultType, wystąpi błąd.

Domyślnie nie ma wizualnego wskaźnika, który informowałby użytkownika o używanym typie. Jednym z łatwych sposobów na odróżnienie typów zmiennych jest kolor.

Dodawanie zmiennych do zestawu narzędzi

Aby ten nowy typ zmiennej był przydatny dla użytkowników, musisz dodać sposób tworzenia i używania nowych zmiennych.

Utwórz nową kategorię dynamiczną zmiennych, jeśli jeszcze jej nie masz.

Otwarta kategoria „Zmienne” zawierająca przycisk „Utwórz zmienną”.

Dodaj nowe metody pobierające i ustawiające do kategorii.

Ta sama kategoria po utworzeniu zmiennych „foo” i „bar”. Zawiera przycisk „Utwórz zmienną”, bloki ustawiania i zmieniania wartości zmiennej oraz bloki pobierania wartości.

Przycisk Utwórz zmienną

Następnie użytkownik musi mieć możliwość tworzenia zmiennych. Najprostszym sposobem jest użycie przycisku „Utwórz zmienną”.

Podczas tworzenia przycisku wywołaj funkcję zwrotną

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

i zostanie utworzona zmienna "Panda".

Najprostszym sposobem umożliwienia użytkownikom tworzenia zmiennych różnych typów jest udostępnienie po jednym przycisku „Utwórz” dla każdego typu (np. Utwórz zmienną tekstową, Utwórz zmienną liczbową, Utwórz zmienną Panda).

Jeśli masz więcej niż 2–3 typy zmiennych, możesz szybko skończyć z zbyt dużą liczbą przycisków. W takim przypadku możesz użyć @blockly/plugin-typed-variable-modal, aby wyświetlić wyskakujące okienko, w którym użytkownicy mogą wybrać odpowiedni typ zmiennej.

Definiowanie generatorów

Na koniec musisz zdefiniować generatory kodu blokowego dla nowych bloków zmiennych. Możesz też uzyskać dostęp do listy zmiennych bezpośrednio za pomocą funkcji Workspace.getVariableMap().getAllVariables(), aby pobrać wszystkie zmienne wszystkich typów, lub Workspace.getVariableMap().getVariablesOfType(), aby pobrać wszystkie zmienne określonego typu.