Variables

Las variables son un concepto de programación importante. Blockly admite lenguajes de escritura dinámica, como Python y JavaScript, y, con un poco de trabajo adicional, puedes agregar información para admitir lenguajes de escritura sólida (o estáticos), como Java o C.

Aquí encontrarás más información sobre los lenguajes de tipo dinámicos en comparación con los de tipo estático.

Blockly proporciona campos variables, que son cuadros desplegables dinámicos que muestran los nombres de las variables que proporcionó el usuario. A continuación, te mostramos un ejemplo de una de estas opciones.

De forma predeterminada, Blockly permite asignar cualquier tipo a una variable, y todos los generadores que proporciona Blockly son para idiomas de escritura dinámica. Si, en cambio, usas un lenguaje escrito, puedes configurar Blockly para que lo admita de la siguiente manera:

Bloques de variables sin tipo

Los bloques más básicos para acceder a una variable y manipularla son los bloques get y set. Analicemos los bloques de métodos get y set que proporciona 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);
    ...
  }
};

Esto crea los siguientes dos bloques:

Un detalle importante que debes tener en cuenta es que, cuando se configura el "output" del método get de la variable como nulo, el valor que se muestra puede ser de cualquier tipo. Además, observa que la entrada del método set de variables no especifica ninguna verificación. Como resultado, la variable se puede establecer en cualquier tipo de valor.

Bloques de variables escritas

Puedes agregar métodos get y set que apliquen la verificación de tipo. Por ejemplo, si creaste una variable de tipo "Panda", las siguientes definiciones crean un método get y un método set con los tipos adecuados.

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

Esto crea dos tipos de bloques: un método get y un método set. Sus menús desplegables solo muestran variables de tipo Panda. Sus entradas y salidas solo aceptan conexiones con el tipo Panda. El defaultType del campo debe establecerse en uno de los valores del array variableTypes. Si no se establece defaultType mientras se proporciona un array variableTypes, se mostrará un error.

De forma predeterminada, no hay un indicador visual que le indique al usuario qué tipo se está usando. Una manera fácil de diferenciar los tipos de variables es mediante el color.

Cómo agregar variables a Toolbox

Para que este nuevo tipo de variable sea útil para tus usuarios, debes agregar una forma de crear y usar las nuevas variables.

Crea una categoría dinámica nueva para las variables si aún no tienes una.

Agrega los métodos get y set nuevos a la categoría.

Botón Crear variable

A continuación, el usuario necesita una forma de crear variables. La forma más sencilla es con un botón “Crear variable”.

Cuando crees el botón, realiza la llamada de devolución de llamada

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

y se creará una variable de tipo Panda.

La forma más fácil de permitir que los usuarios creen variables de varios tipos es tener un botón “crear” por tipo (p.ej., Crear variable de string, Crear variable de número, Crear variable de Panda).

Si tienes más de dos o tres tipos de variables, puedes terminar con demasiados botones rápidamente. En ese caso, considera usar @blockly/plugin-typed-variable-modal para mostrar una ventana emergente desde la cual los usuarios pueden seleccionar el tipo de variable deseado.

Define generadores

Por último, deberás definir los generadores de código de bloque para tus bloques de variables nuevos. También puedes acceder a la lista de variables directamente con Blockly.Workspace.getAllVariables() para obtener todas las variables de todos los tipos o con Blockly.Workspace.getVariablesOfType() para obtener todas tus variables de un tipo específico.