Las variables son un concepto de programación importante. Blockly admite lenguajes con escritura dinámica, como Python y JavaScript, y, con un poco de trabajo adicional, puedes agregar información para admitir lenguajes con escritura sólida (o lenguajes con escritura estática), como Java o C.
Para obtener más información sobre los lenguajes con escritura dinámica y estática, consulta Introducción a los tipos de datos: estáticos, dinámicos, sólidos y débiles.
Blockly proporciona campos de 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 forma predeterminada, Blockly permite que se asigne cualquier tipo a una variable, y todos los generadores proporcionados por Blockly son para lenguajes con escritura dinámica. Si usas un lenguaje con escritura, puedes configurar Blockly para que lo admita de la siguiente manera:
- Especifica un tipo de variable y sus bloques, incluidos los getters y setters.
- Configura la caja de herramientas para usar tu tipo de variable y tus bloques.
- Define generadores para las variables y sus bloques.
Bloques de variables sin tipo
Los bloques más básicos para acceder a una variable y manipularla son los bloques getter y setter. Veamos los bloques getter y setter 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 se debe tener en cuenta es que, si se establece el "resultado" del getter de la variable como nulo, el valor de devolución puede ser de cualquier tipo. Además, observa que la entrada del establecedor de variables no especifica ninguna verificación. Como resultado, la variable se puede establecer en cualquier tipo de valor.
Bloques de variables con tipo
Puedes agregar métodos getter y setter que apliquen la verificación de tipos. Por ejemplo, si creaste una variable de tipo "Panda"
, las siguientes definiciones crean un getter y un setter 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 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);
...
}
};
Esto crea dos tipos de bloques: un getter y un setter. Sus menús desplegables solo muestran variables de tipo "Panda"
. Sus entradas y salidas solo aceptan conexiones de tipo "Panda"
. El defaultType
del campo debe establecerse en uno de los valores del array variableTypes
. Si no se configura defaultType
cuando se proporciona un array variableTypes
, se generará un error.
De forma predeterminada, no hay ningún indicador visual que le indique al usuario qué tipo se está usando. Una forma sencilla de diferenciar los tipos de variables es por color.
Cómo agregar variables a la caja de herramientas
Para que este nuevo tipo de variable sea útil para los usuarios, debes agregar una forma de crear y usar las variables nuevas.
Crea una nueva categoría dinámica para las variables si aún no tienes una.
Agrega los nuevos métodos get y set 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 un botón "Crear variable".
Cuando crees el botón, haz la llamada de devolución de llamada
Blockly.Variables.createVariableButtonHandler(button.getTargetWorkspace(), null, 'panda');
y se creará una variable con tipo "Panda"
.
La forma más sencilla de permitir que los usuarios creen variables de varios tipos es tener un botón "Crear" por tipo (p.ej., Crear variable de cadena, Crear variable numérica, Crear variable de Panda).
Si tienes más de dos o tres tipos de variables, puedes terminar rápidamente con demasiados botones. En ese caso, considera usar @blockly/plugin-typed-variable-modal para mostrar una ventana emergente desde la que los usuarios puedan seleccionar el tipo de variable que deseen.
Cómo definir generadores
Por último, deberás definir generadores de código en bloque para tus nuevos bloques de variables. También puedes acceder a la lista de variables directamente con Workspace.getVariableMap().getAllVariables()
para obtener todas las variables de todos los tipos o Workspace.getVariableMap().getVariablesOfType()
para obtener todas las variables de un tipo específico.