As variáveis são um conceito importante de programação. O Blockly oferece suporte a linguagens com tipagem dinâmica, como Python e JavaScript, e com um pouco de trabalho extra, é possível adicionar informações para oferecer suporte a linguagens com tipagem forte (ou linguagens com tipagem estática), como Java ou C.
Confira mais informações sobre linguagens com tipagem dinâmica e estática.
O Blockly fornece campos variáveis, que são caixas suspensas dinâmicas que mostram os nomes das variáveis fornecidas pelo usuário. Confira um exemplo abaixo.
Por padrão, o Blockly permite que qualquer tipo seja atribuído a uma variável, e todos os geradores fornecidos pelo Blockly são para linguagens com tipagem dinâmica. Se você estiver usando um idioma digitado, configure o Blockly para oferecer suporte a ele fazendo o seguinte:
- Especifique um tipo de variável e os blocos dela, incluindo getters e setters.
- Configure a caixa de ferramentas para usar o tipo de variável e os blocos.
- Defina geradores para variáveis e blocos delas.
Blocos de variáveis não tipadas
Os blocos mais básicos para acessar e manipular uma variável são os blocos getter e setter. Vamos analisar os blocos getter e setter fornecidos pelo 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);
...
}
};
Isso cria os dois blocos a seguir:
Um detalhe importante é que, ao definir a "saída" do getter da variável como nula, o valor de retorno pode ser de qualquer tipo. Além disso, a entrada do setter de variáveis não especifica nenhuma verificação. Como resultado, a variável pode ser definida para qualquer tipo de valor.
Blocos de variáveis digitadas
É possível adicionar getters e setters que aplicam a verificação de tipo. Por exemplo, se você criou uma variável do tipo "Panda", as definições a seguir criam um getter e um setter com os tipos apropriados.
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);
...
}
};
Isso cria dois tipos de blocos, um getter e um setter. Os menus suspensos só
mostram variáveis do tipo Panda. As entradas e saídas aceitam apenas conexões do tipo Panda. O defaultType
do campo precisa ser definido como um
dos valores no array variableTypes
. Não definir defaultType
ao
fornecer uma matriz variableTypes
vai causar um erro.
Por padrão, não há um indicador visual para informar ao usuário qual tipo está sendo usado. Uma maneira fácil de diferenciar os tipos de variáveis é pela cor.
Adicionar variáveis à Toolbox
Para que esse novo tipo de variável seja útil para os usuários, você precisa adicionar uma maneira de criar e usar as novas variáveis.
Crie uma categoria dinâmica para variáveis, se ainda não tiver uma.
Adicione os novos getters e setters à categoria.
Botão "Criar variável"
Em seguida, o usuário precisa de uma maneira de criar variáveis. A maneira mais simples é com um botão "Criar variável".
Ao criar o botão, faça a chamada de callback
Blockly.Variables.createVariableButtonHandler(button.getTargetWorkspace(), null, 'panda');
e uma variável do tipo Panda será criada.
A maneira mais fácil de permitir que os usuários criem variáveis de vários tipos é ter um botão "Criar" por tipo (por exemplo, Criar variável de string, Criar variável de número, Criar variável Panda).
Se você tiver mais de dois ou três tipos de variáveis, poderá acabar com muitos botões. Nesse caso, use @blockly/plugin-typed-variable-modal para mostrar um pop-up em que os usuários podem selecionar o tipo de variável desejado.
Definir geradores
Por fim, você vai precisar definir geradores de código de bloco para os novos blocos de variáveis. Também é possível acessar a lista de variáveis diretamente com Blockly.Workspace.getAllVariables() para receber todas as variáveis de todos os tipos ou Blockly.Workspace.getVariablesOfType() para receber todas as variáveis de um tipo específico.