Variables

Las variables son un concepto importante de programación. Blockly admite de forma dinámica lenguajes escritos, como Python y JavaScript, y, con un poco de trabajo adicional, puede agregar información para admitir lenguajes con tipado fuerte (o lenguajes) como Java o C.

Aquí hay más información sobre lenguajes escritos dinámicos versus estáticos.

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

De forma predeterminada, Blockly permite asignar cualquier tipo a una variable y todos Los generadores que ofrece Blockly son para idiomas que se escriben de forma dinámica. Si eres con un lenguaje escrito, puedes configurar Blockly para que lo admita lo siguiente:

Bloques de variables sin tipo

Los bloques más básicos para acceder a una variable y manipularla son el método get y bloques set. Analicemos los bloques get y set que Blockly proporciona.

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 a tener en cuenta es que al establecer el “resultado” del método get de la variable como nulo, el valor que se devuelve puede ser de cualquier tipo. Además, observa que la variable la entrada del método set no especifica ninguna verificación. Como resultado, la variable se puede establecer a 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 crearon una variable de tipo "Panda", las siguientes definiciones crean un métodos get y 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. Solo sus menús desplegables mostrar variables de tipo Panda. Sus entradas y salidas solo aceptan conexiones con el tipo Panda. El defaultType del campo se debe establecer en uno de los valores del array variableTypes. No se está estableciendo defaultType mientras Si proporcionas un array variableTypes, se generará un error.

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

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.

Crear una nueva categoría dinámica de 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, tu usuario necesita una forma de crear variables. La forma más sencilla es con una "Crear variable" botón.

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 "crear" botón por tipo (p.ej., Crear variable de cadena, Crear número crear una variable de Panda).

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

Definir generadores

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