Ao longo dos anos, a equipe da Blockly e da Blockly Games aprendeu muitas lições que se aplicam a quem desenvolve novos blocos. Confira a seguir uma coleção de erros que cometemos ou erros comumente cometidos por outras pessoas.
Essas são lições gerais que aprendemos usando o estilo visual do Blockly e podem não se aplicar a todos os casos de uso ou projetos. Existem outras soluções. Isso é também não é uma lista completa dos problemas que os usuários podem encontrar e como evitar para resolvê-los com rapidez. Cada caso é um pouco diferente e tem suas vantagens e desvantagens.
1. Condicionais x repetições
Os blocos mais difíceis para novos usuários são condicionais e loops. Muitas os ambientes baseados em blocos agrupam ambos os blocos nos mesmos "Controles" com os dois blocos tendo a mesma forma e a mesma cor. Isso muitas vezes leva à frustração, porque novos usuários confundem os dois blocos. O Blockly recomenda mover condicionais e repetições para uma "lógica" separada. e "Repetições" categorias, cada uma com uma cor diferente. Isso deixa claro que são ideias distintas que se comportam de maneira diferente, apesar de terem formas semelhantes.
Recomendação: mantenha condicionais e repetições separados.
2. Listas baseadas em um
Programadores novatos reagem mal ao encontrar listas baseadas no zero pela primeira tempo de resposta. Por isso, Blockly segue a liderança de Lua e Lambda Moo criando listas e indexação de strings com base em um.
Para usos mais avançados do Blockly, as listas baseadas em zero são compatíveis a transição para texto mais fácil. Para públicos mais jovens ou iniciantes a indexação com base em um ainda é recomendada.
Recomendação: um é o primeiro número.
3. Entradas do usuário
Há três maneiras de receber um parâmetro do usuário. Um menu suspenso é o mais restritivo e é bom para tutoriais e exercícios simples. Um campo de entrada permite mais liberdade e é bom para atividades mais criativas. Um bloco de valor entrada (geralmente com um bloco sombra) oferece a oportunidade de calcular um valor (por exemplo, um gerador aleatório) em vez de apenas um valor estático.
Recomendação: escolha um método de entrada apropriado para seus usuários.
4. Imagens de blocos em tempo real
A documentação dos blocos deve incluir imagens dos blocos aos quais ela se refere Fazer capturas de tela é fácil. Mas, se houver 50 imagens assim, aplicativo é traduzido para 50 idiomas, de repente um está mantendo 2.500 imagens estáticas. Depois, o esquema de cores muda e 2.500 imagens precisam ser atualizadas - novamente.
Para sair desse pesadelo com a manutenção, o Blockly Games substituiu todas as capturas de tela com instâncias do Blockly em execução no modo somente leitura. O resultado parece idêntico a uma imagem, mas com a garantia de estar atualizado. Somente leitura tornou a internacionalização possível.
Recomendação: se você oferece suporte a mais de um idioma, use o modo somente leitura.
5. Seu outro lado esquerdo
Feedback de crianças nos EUA (embora curiosamente não sejam de outros países) revelou uma confusão enorme entre a esquerda e a direita. Isso foi resolvido com o adição de setas. Se a direção for relativa (a um avatar, por exemplo), o o estilo da seta é importante. Uma → seta reta ou uma seta para virar ↱ está confusa quando o avatar está voltado para a direção oposta. O mais útil é um círculo ⟳ seta, mesmo nos casos em que o ângulo girado é menor do que o indicado pela seta.
Recomendação: complemente o texto com ícones Unicode sempre que possível.
6. Blocos de alto nível
Sempre que possível, uma abordagem de nível mais alto deve ser adotada, mesmo que reduza desempenho de execução ou flexibilidade. Considere esta expressão do Apps Script:
SpreadsheetApp.getActiveSheet().getDataRange().getValues()
Em um mapeamento 1:1, que preserva todos os recursos potenciais, os expressão seria criada usando quatro blocos. Mas a Blockly busca uma abordagem e forneceria um bloco que encapsulasse toda a expressão. O objetivo é otimizar para o caso de 95%, mesmo que isso dificulte os 5% restantes. O Blockly não substitui idiomas de texto, mas para ajudar os usuários a superar a curva de aprendizado inicial para que possam usar linguagens baseadas em texto.
Recomendação: não converta toda a API em blocos às cegas.
7. Valores de retorno opcionais
Muitas funções na programação baseada em texto realizam uma ação e depois retornam
um valor. É possível usar ou não esse valor de retorno. Um exemplo é o plano
função pop()
. O pop pode ser chamado para obter e remover o último elemento,
ou pode ser chamado para apenas remover o último elemento com o valor de retorno
sendo ignorados.
var last = stack.pop(); // Get and remove last element. stack.pop(); // Just remove last element.
Geralmente, as linguagens baseadas em blocos não são boas em ignorar um valor de retorno. Um bloco de valor precisa ser conectado a algo que aceite o valor. Existem várias estratégias para lidar com esse problema.
a) Resolver o problema. A maioria das linguagens baseadas em blocos para evitar esses casos. Por exemplo, o Scratch não tem blocos que efeitos colaterais e um valor de retorno.
b) Forneça dois blocos. Se o espaço na caixa de ferramentas não for um problema, uma simples solução é fornecer dois de cada tipo de bloco, um com e outro sem um valor de retorno. A desvantagem é que isso pode gerar um erro com muitos blocos quase idênticos.
c) Transformar um bloco. Use um menu suspenso, uma caixa de seleção ou outro controle que permita que o usuário escolha se há um valor de retorno ou não. O bloco muda de forma dependendo das opções. Um exemplo disso pode ser que aparece no bloco de acesso à lista do Blockly.
d) Consumir o valor. A primeira versão do App Inventor criava um pipe especial, bloco que comeu qualquer valor conectado. Os usuários não entenderam o conceito, e a segunda versão do App Inventor removeu o bloco de barra vertical e, em vez recomendado que os usuários apenas atribuam o valor a uma variável descartável.
Recomendação: cada estratégia tem seus prós e contras, escolha a opção certa para cada caso seus usuários.
8. Blocos crescentes
Alguns blocos podem exigir um número variável de entradas. Exemplos são uma um bloco de adição que soma um conjunto arbitrário de números, ou um argumento if/elseif/else com um conjunto arbitrário de cláusulas elseif ou um construtor de lista com um número arbitrário de elementos inicializados. Há várias estratégias, cada uma com suas vantagens e desvantagens.
a) A abordagem mais simples é fazer com que o usuário componha o bloco com base em objetos blocos. Um exemplo seria adicionar três números, aninhando dois números blocos de adição. Outro exemplo seria fornecer apenas blocos if/else, e fazendo com que o usuário as aninhe para criar condições elseif.
A vantagem dessa abordagem é sua simplicidade inicial (tanto para o usuário pelo desenvolvedor). A desvantagem é que, nos casos em que há uma grande de aninhamentos, o código se torna muito complicado para o usuário ler e manter.
b) Uma alternativa é expandir dinamicamente o bloco para que sempre haja um entrada livre no final. Da mesma forma, o bloco exclui a última entrada se houver duas entradas sem custo financeiro no final. Essa é a abordagem com que a primeira versão O App Inventor foi usado.
Alguns usuários do App Inventor não gostaram dos bloqueios que crescem automaticamente vários motivos. Primeiro, sempre houve uma contribuição sem custo financeiro e o programa nunca foi "concluído". Em segundo lugar, a inserção de um elemento no meio da pilha frustrante pois envolvia desconectar todos os elementos abaixo da edição e depois de reconectá-las. Dito isso, se a ordem não for importante, e os usuários podem ser confortável com buracos em seu programa, esta é uma opção muito conveniente.
c) Para resolver o problema do buraco, alguns desenvolvedores adicionam botões +/- aos blocos que adicionar ou remover entradas manualmente. Open Roberta usa dois desses botões para adicionar ou remover entradas da parte inferior. Outros desenvolvedores adicionam dois botões em cada para que a inserção e a exclusão do meio da pilha possam ser acomodado. Outros adicionam dois botões para cima/para baixo em cada linha de modo que a reordenação da pilha podem ser acomodadas.
Essa estratégia é um espectro de opções que varia de apenas dois botões por bloco, a quatro botões por linha. Por um lado, há o perigo de que os usuários não para realizar as ações de que precisam, do outro lado, a IU está tão preenchida com que parece a ponte da nave espacial Enterprise.
d) A abordagem mais flexível é adicionar um balão mutador ao bloco. Isso é representado como um único botão que abre uma caixa de diálogo de configuração do bloco de recursos dependente. Os elementos podem ser adicionados, excluídos ou reorganizados à vontade.
A desvantagem dessa abordagem é que as mutações não são intuitivas para iniciantes. A introdução de mutadores exige algum tipo de instrução. Os aplicativos baseados em bloqueio que segmentam crianças mais novas não podem usar mutadores. Apesar de serem aprendidas, elas são inestimáveis para usuários avançados.
Recomendação: cada estratégia tem seus prós e contras, escolha a opção certa para cada caso seus usuários.
9. Geração de código limpo
Usuários avançados do Blockly podem conferir o código gerado (JavaScript, Python, PHP, Lua, Dart etc.) e reconhecer imediatamente o programa criado por ele. Isso significa que é necessário fazer um esforço extra para manter esse código gerado automaticamente legível. Parênteses supérfluos, variáveis numéricas, espaços em branco esmagados modelos de código detalhados atrapalham a produção de um código elegante. O código gerado deve incluir comentários e estar em conformidade com guias de estilo do Google.
Recomendação: tenha orgulho do código gerado. Mostre ao usuário.
10. Dependência do idioma
Um efeito colateral da vontade de código limpo é que o comportamento do Blockly definida em termos de como a linguagem de compilação cruzada se comporta. A maior linguagem de saída comum é JavaScript, mas se o Blockly realizar a compilação cruzada para outro idioma, não devem ser feitas tentativas injustificadas para preservar a comportamento exato em ambas as linguagens. Por exemplo, em JavaScript, um valor string é falsa, enquanto em Lua é verdadeira. Definir um único padrão de de execução do código do Blockly, independentemente da linguagem de destino resultam em um código sem manutenção que parece ter saído do compilador do GWT.
Recomendação: o Blockly não é um idioma. Permita que o idioma atual afetar o comportamento.