Variabili

Le variabili sono un concetto di programmazione importante. Blockly supporta linguaggi con tipi dinamici come Python e JavaScript e, con un po' di lavoro extra, puoi aggiungere informazioni per supportare linguaggi con tipi forti (o linguaggi con tipi statici) come Java o C.

Per saperne di più sui linguaggi con tipi dinamici e statici, consulta Introduzione ai tipi di dati: statici, dinamici, forti e & deboli.

Blockly fornisce campi di variabili che sono caselle di elenco a discesa dinamiche che mostrano i nomi delle variabili fornite dall'utente. Di seguito è riportato un esempio.

Un campo variabile con un menu a discesa per scegliere una variabile, modificare il nome della variabile corrente o eliminare la variabile corrente.

Per impostazione predefinita, Blockly consente di assegnare qualsiasi tipo a una variabile e tutti i generatori forniti da Blockly sono per linguaggi con tipi dinamici. Se utilizzi un linguaggio con tipi, puoi configurare Blockly per supportarlo procedendo nel seguente modo:

Blocchi di variabili senza tipi

I blocchi più semplici per accedere a una variabile e manipolarla sono i blocchi getter e setter. Esaminiamo i blocchi getter e setter forniti da 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);
    ...
  }
};

Vengono creati i due blocchi seguenti:

Blocchi getter e setter per la variabile
`foo`.

Un dettaglio importante da notare è che, impostando l'opzione "output" del getter della variabile su null, il valore restituito può essere di qualsiasi tipo. Inoltre, tieni presente che l'input del setter della variabile non specifica alcun controllo. Di conseguenza, la variabile può essere impostata su qualsiasi tipo di valore.

Blocchi di variabili con tipi

Puoi aggiungere getter e setter che applicano il controllo dei tipi. Ad esempio, se hai creato una variabile di tipo "Panda", le seguenti definizioni creano un getter e un setter con i tipi appropriati.

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

Vengono creati due tipi di blocchi, un getter e un setter. I relativi elenchi a discesa mostrano solo le variabili di tipo "Panda". I relativi input e output accettano solo connessioni di tipo "Panda". Il defaultType del campo deve essere impostato su uno dei valori dell'array variableTypes. Se non imposti defaultType mentre fornisci un array variableTypes, verrà generato un errore.

Per impostazione predefinita, non è presente alcun indicatore visivo per comunicare all'utente il tipo utilizzato. Un modo semplice per distinguere i tipi di variabili è utilizzare i colori.

Aggiungere variabili alla toolbox

Per rendere utile questo nuovo tipo di variabile per gli utenti, devi aggiungere un modo per creare e utilizzare le nuove variabili.

Crea una nuova categoria dinamica per le variabili, se non ne hai già una.

Una categoria aperta denominata "Variabili" contenente un pulsante "Crea variabile".

Aggiungi i nuovi getter e setter alla categoria.

La stessa categoria dopo la creazione delle variabili "foo" e "bar". Contiene un pulsante "Crea variabile", blocchi set-variable-to e change-variable-by e blocchi getter.

Crea pulsante per la variabile

Successivamente, l'utente deve avere un modo per creare le variabili. Il modo più semplice è utilizzare un "Crea variabile" pulsante.

Quando crei il pulsante, fai in modo che il callback chiami

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

e verrà creata una variabile di tipo "Panda".

Il modo più semplice per consentire agli utenti di creare variabili di più tipi è avere un pulsante "Crea" per ogni tipo (ad es. Crea variabile stringa, Crea variabile numerica, Crea variabile panda).

Se hai più di due o tre tipi di variabili, potresti ritrovarti rapidamente con troppi pulsanti. In questo caso, valuta la possibilità di utilizzare @blockly/plugin-typed-variable-modal per visualizzare un popup da cui gli utenti possono selezionare il tipo di variabile desiderato.

Definire i generatori

Infine, dovrai definire i generatori di blocchi di codice per i nuovi blocchi di variabili. Puoi anche accedere direttamente all'elenco delle variabili con Workspace.getVariableMap().getAllVariables() per ottenere tutte le variabili di tutti i tipi o Workspace.getVariableMap().getVariablesOfType() per ottenere tutte le variabili di un tipo specifico.