Perl – Arrays – parte I

Em Perl um array representa uma lista de valores indexados a partir de zero. Uma variável array tem o prefixo @ lembrando a palavra array (ou @rray,) assim como uma variável escalar tem o prefixo $ lembrando a palavra scalar (ou $calar). A seguir temos um exemplo de script contendo arrays.

  • Design-time
use warnings;
use strict;
print uc("\nArray é uma variável que fornece armazenamento dinâmico para listas\n\n");
print "\t\t my \@frase = qw#Esta é 30 lista#;";
my @frase = qw#Esta é 30 lista#;
print "\nprint \@frase; \t\t\t";
print @frase;
print "\n\nNúmero de elementos:\t\tmy \$count = scalar \@frase;";
my $count = scalar @frase;			#my $count = @frase;
print "\nprint \$count; \t\t\t";
print $count;
print "\n\nMaior índice:\t\t\tmy \$last = \$#frase;";
my $last = $#frase;
print "\nprint \$last; \t\t\t";
print $last;
print "\n\nPrimeiro elemento:";
print "\nprint \$frase[0]; \t\t";
print $frase[0];				#print @frase[0];
print "\n\nPrimeiro e terceiro elementos:";
print "\nprint \@frase[0,2]; \t\t";
print @frase[0,2];
print "\n\nÚltimo elemento:";
print "\nprint \$frase[\$last]; \t\t";
print $frase[$last];
print "\n\n\t\t my \@sub_frase = \@frase[0..2];";
my @sub_frase = @frase[0..2];
print "\nprint \@sub_frase; \t\t";
print @sub_frase;
print "\n\t\t \@sub_frase = \@frase[-2..-1];";
@sub_frase = @frase[-2..-1];
print "\nprint \@sub_frase; \t\t";
print @sub_frase;
print "\n\n\t\t my \@dia = qw(Seg Ter Qua Qui Sex Sab Dom);";
my @dia = qw(Seg Ter Qua Qui Sex Sab Dom);
print "\nprint \@dia; \t\t\t";
print @dia;
print "\n\$dia[0] = \"Segunda\"; \t\t";
$dia[0] = "Segunda";
print "\nprint \@dia; \t\t\t";
print @dia;
print "\n\@dia[1..\$#dia] = qw(Terça Quarta Quinta Sexta Sábado Domingo); \t\t";
@dia[1..$#dia] = qw(Terça Quarta Quinta Sexta Sábado Domingo);
print "\nprint \@dia; \t\t\t";
print @dia;
print "\n\n";
  • Runtime
Script Perl rodando em Ubuntu 22.04 Jammy Jellyfish, captura de tela com Peek
  • Sintaxe

Observe nas primeiras linhas o uso do comando use para carregamento dos pragmas warnings e strict. Assim se providenciam avisos e captura de erros. A primeira consequência é a necessidade do uso da palavra-chave my precedendo o nome de uma variável sempre que esta for declarada dentro de um determinado escopo.

Em um contexto escalar, cada elemento do array pode ser obtido da seguinte forma:

$nome_do_array [ índice ]

onde índice vai de 0 até o valor retornado pela variável especial $#nome_do_array, que representa o último elemento do array.

Se optarmos por índices negativos, estes iriam de -($#nome_do_array + 1) até -1.

Também em contexto escalar, o número de elementos de um array pode ser obtido pelo próprio nome do array:

$nome_do_array

Observe com cuidado a listagem (design-time) e o script em execução (runtime) para esclarecer prováveis dúvidas e assim obter um completo entendimento.

  • Reflexão – A História sempre se repete por causa da ignorância e da alienação

Desde sua primeira campanha eleitoral à presidência em 2018, quando bradava “Brasil acima de tudo, Deus acima de todos”, adaptação preferida pelos nazistas do verso “Deutschland über alles”, frequentemente o presidente Jair Bolsonaro faz referências ao slogan fascista “Deus, Pátria e Família”, ou às variantes “Deus, Pátria, Família e Liberdade” ou “Deus, Pátria, Família e Trabalho”. Samuel Johnson estava certo ao afirmar que “o patriotismo é o último refúgio do canalha”. Mas como bolsomínion mal sabe ler, cabem aqui algumas ilustrações.

Perl – Listas

Em Perl uma lista é uma coleção ou sequência de valores escalares. Parênteses e vírgulas são operadores para se construir uma lista. Cada valor na lista é chamado de elemento da lista. Os elementos da lista são indexados e ordenados. Você pode se referir a cada elemento por sua posição. Vejamos este simples exemplo. Em um próximo post veremos qual é utilidade das listas.

Design-time

print uc("\nLista é uma coleção ou sequência de valores escalares");
print "\n\tListas vazias:";
print "\nprint ();";
print ();
print "\nprint (());";
print (());
print "\n\n\tLista de inteiros:";
print "\nprint (10 , 20 , 30);\t\t\t\t\t";
print (10 , 20 , 30);
print "\nPrimeiro elemento:";
print "\nprint ((10 , 20 , 30)[0]);\t\t\t\t";
print ((10 , 20 , 30)[0]);
print "\nPrimeiro e último elementos:";
print "\nprint ((10 , 20 , 30)[0,2]);\t\t\t\t";
print ((10 , 20 , 30)[0,2]);
print "\n\n\tLista de strings:";
print "\nprint ('Esta' , 'é' , 'outra' , 'lista');\t\t";
print ('Esta' , 'é' , 'outra' , 'lista');
print "\nPrimeiro elemento:";
print "\nprint (('Esta' , 'é' , 'outra' , 'lista')[0]);\t\t";
print (('Esta' , 'é' , 'outra' , 'lista')[0]);
print "\nPrimeiro e terceiro elementos:";
print "\nprint (('Esta' , 'é' , 'outra' , 'lista')[0,2]);\t";
print (('Esta' , 'é' , 'outra' , 'lista')[0,2]);
print "\n\n\tFaixas são listas também:";
print "\nprint (0..9);\t\t\t\t\t\t";
print (0..9);
print "\nprint (a..z);\t\t\t\t\t\t";
print (a..z);
print "\n\n\tListas podem ser complexas:";
print "\nprint (10 , (\"é\", 30), (a..c));\t\t\t\t";
print (10 , ("é", 30), (a..c));
print "\n\n\tUsando qw com delimitadores não-alfanuméricos:";
print "\nprint qw#Esta é 30 lista#;\t\t\t\t";
print qw#Esta é 30 lista#;
print "\n\n";

Runtime

Script Perl rodando em Ubuntu 22.04 Jammy Jellyfish, captura com Peek

Sintaxe

As listas devem ser envolvidas por parênteses. No entanto, os parênteses não são obrigatórios, exceto nas linhas 12, 15, 21 e 24, que imprimem elementos (identificados por um inteiro entre colchetes) em uma dada posição na lista.

Observe na linha 31 o caractere de escape precedendo as aspas duplas (\”). Como a string está envolvida por aspas duplas, uma representação delas dentro da string precisa ser precedida pelo caractere de escape (\). Uma alternativa seria usar aspas simples (), dentro de uma string envolvida por aspas duplas.

Veja na linha 32 que, se há listas dentro de uma lista, então a impressão dessa lista a considera como se fosse apenas uma lista, sem listas internas.

Reflexão

Falemos dos conselhos… Fernando Sabino, o que são as coisas?
São como são e não deveriam ser ou gostaríamos que elas fossem.

E o que não tem solução?
O que não tem solução, solucionado está, não adianta gastar boa vela com mau defunto.

E as coisas mudam, conselheiro?
Se mudou, é porque não deu certo!

Para antes de entrar…
Veja por onde sair!

Um bom conselho?
Faça somente o que gosta. Para isso, passe a gostar do que faz.

A melhor forma de resolver um problema é…
A única forma de resolver um problema é primeiro resolver o do outro.

E no fim, dá certo?
Se não deu, é porque você não chegou ao fim.

E as listas?
Tenho um fraco por listas. Listas de tudo: das pessoas simpáticas que conheço, ou das mais chatas; dos livros que gostaria de já ter lido; dos melhores filmes que já vi…

E a aquela das pequenas coisas que o desagradam, tem o que?
Tampa de pasta de dentes, roupa sob medida, comprar a prestação, retirar gelo da forma da geladeira, esperar o que quer que seja, até mesmo pagamento! Salas de espera, vento, buzina, luz florescente, motocicleta, copo de plástico, poema lido pelo artista, a frase “você está lembrando de mim?”

E por que a implicância com a tampa da pasta de dente?
Porque ela escapole da mão, cai no ralo da pia e é uma desgraça tentar tirá-la…

E das coisas que agradam?
Dia de chuva sem precisar sair de casa, carta que não exige resposta, conseguir desfazer um compromisso sem precisar mentir, pagar a última prestação, a frase “está tudo pago”, chegar atrasado no teatro e o espetáculo não ter começado, a frase “tenho uma boa notícia para você”, cinema sem fila, descobrir que ainda é cedo, dá tempo de tomar mais um, sabonete novo, fazer lista das pequenas coisas que realmente agradam…

Perl – Operadores – parte III

Vamos usar os operadores relacionais e lógicos com strings?

  • Design-time
#solicita 2 strings e realiza operações relacionaiscd Docuemntos e lógicas
#usa operador ternário: (operação relacional ou lógica) ? 1 : 0

print "Informe a primeira string: ";
chomp($s1 = <STDIN>);
print "Informe a segunda string: ";
chomp($s2 = <STDIN>);
print "\n\t\tOPERAÇÕES RELACIONAIS\n\n";

print "Igual \t\t $s1 eq $s2 \t\t", $s1 eq $s2 ? 1 : 0, "\n";
print "Diferente \t $s1 ne $s2 \t\t", $s1 ne $s2 ? 1 : 0, "\n";
print "Maior \t\t $s1 gt $s2 \t\t", $s1 gt $s2 ? 1 : 0, "\n";
print "Maior ou igual \t $s1 ge $s2 \t\t", $s1 ge $s2 ? 1 : 0, "\n";
print "Menor \t\t $s1 lt $s2 \t\t", $s1 lt $s2 ? 1 : 0, "\n";
print "Menor ou igual \t $s1 le $s2 \t\t", $s1 le $s2 ? 1 : 0, "\n";
print "Comparação \t $s1 cmp $s2 \t\t", $s1 cmp $s2, "\n";

print "\n\t\tOPERAÇÕES LÓGICAS\n\n";

print "E\t($s1 eq $s2) && ($s1 eq $s2) \t", ($s1 eq $s2) && ($s1 eq $s2) ? 1 : 0, "\n";
print "\t($s1 eq $s2) && ($s1 ne $s2) \t", ($s1 eq $s2) && ($s1 ne $s2) ? 1 : 0, "\n";
print "\t($s1 ne $s2) && ($s1 eq $s2) \t", ($s1 ne $s2) && ($s1 eq $s2) ? 1 : 0, "\n";
print "\t($s1 ne $s2) && ($s1 ne $s2) \t", ($s1 ne $s2) && ($s1 ne $s2) ? 1 : 0, "\n\n";

print "Ou\t($s1 eq $s2) || ($s1 eq $s2) \t", ($s1 eq $s2) || ($s1 eq $s2) ? 1 : 0, "\n";
print "\t($s1 eq $s2) || ($s1 ne $s2) \t", ($s1 eq $s2) || ($s1 ne $s2) ? 1 : 0, "\n";
print "\t($s1 ne $s2) || ($s1 eq $s2) \t", ($s1 ne $s2) || ($s1 eq $s2) ? 1 : 0, "\n";
print "\t($s1 ne $s2) || ($s1 ne $s2) \t", ($s1 ne $s2) || ($s1 ne $s2) ? 1 : 0, "\n\n";

print "Não\tnot($s1 eq $s2) \t\t\t", !($s1 eq $s2) ? 1 : 0, "\n";
print "\tnot($s1 ne $s2) \t\t\t", !($s1 ne $s2) ? 1 : 0, "\n\n";

Runtime

Perl rodando em Ubuntu 22.04 (Jammy Jellyfish), captura de tela com Peek
  • Sintaxe

Quando os operandos são strings, e não números, as operações relacionais são realizadas com operadores diferentes, conforme tabela a seguir,

Operações relacionaisNúmerosStrings
Igual==eq
Diferente!=ne
Maior>gt
Maior ou igual>=ge
Menor<lt
Menor ou igual<=le
Comparação<=>cmp

Exceto na operação relacional de comparação, novamente optamos por empregar o operador ternário porque Perl não faz diferença entre as variáveis escalares 0, “0” e “”.

  • Reflexão

Segundo Churchill, “a democracia é a pior forma de governo, à exceção de todos os outros já experimentados ao longo da história”. Por isso, a democracia tem estado sob constante risco. Em recente debate na TV Bandeirantes, um candidato laranja e cabo eleitoral do presidente, travestido de padre, referindo-se ao Censo de 2010, lembrou que 88% da população brasileira é cristã, com maioria católica. Na Alemanha nazista, 94% eram cristãos, com maioria protestante. Nunca antes na história deste país a religião foi tão protagonista no processo eleitoral. Cristãos e maçons são a maioria de conservadores, elegendo e sendo eleitos, tanto no poder legislativo como no executivo. Neste primeiro turno, um inútil general eleito senador revelou o que o nazifascismo miliciano pretende fazer caso vença no segundo turno: tomar o judiciário através do aumento de ministros do STF da mesma forma que fez a quartelada de 1964.

Allegro – Oi, mundo!

Allegro é uma biblioteca multiplataforma voltada principalmente para videogames e programação multimídia. Ele lida com tarefas comuns de baixo nível, como criar janelas, aceitar entrada do usuário, carregar dados, desenhar imagens, reproduzir sons, etc. e geralmente abstrair a plataforma subjacente. No entanto, Allegro não é um game engine: você é livre para projetar e estruturar seu programa como quiser.

  • Design-time
//gcc hello.c -o hello $(pkg-config allegro-5 allegro_font-5 --libs --cflags)
#include <allegro5/allegro5.h>
#include <allegro5/allegro_font.h>
#include <stdbool.h>

int main()
{
    al_init();
    al_install_keyboard();

    ALLEGRO_TIMER* timer = al_create_timer(1.0 / 30.0);
    ALLEGRO_EVENT_QUEUE* queue = al_create_event_queue();
    ALLEGRO_DISPLAY* disp = al_create_display(320, 200);
    ALLEGRO_FONT* font = al_create_builtin_font();

    al_register_event_source(queue, al_get_keyboard_event_source());
    al_register_event_source(queue, al_get_display_event_source(disp));
    al_register_event_source(queue, al_get_timer_event_source(timer));

    bool redraw = true;
    ALLEGRO_EVENT event;

    al_start_timer(timer);
    while(1)
    {
        al_wait_for_event(queue, &event);

        if(event.type == ALLEGRO_EVENT_TIMER)
            redraw = true;
        else if((event.type == ALLEGRO_EVENT_KEY_DOWN) || (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE))
            break;

        if(redraw && al_is_event_queue_empty(queue))
        {
            al_clear_to_color(al_map_rgb(255, 0, 0));
            al_draw_text(font, al_map_rgb(0, 255, 0), 110, 90, 0, "Oi, esperança!");
            al_flip_display();

            redraw = false;
        }
    }

    al_destroy_font(font);
    al_destroy_display(disp);
    al_destroy_timer(timer);
    al_destroy_event_queue(queue);

    return 0;
}
  • Runtime
Allegro rodando no Ubuntu 22.04 (Jammy Jellyfish), captura com Peek
  • Sintaxe

Este exemplo é uma adaptação do código-fonte disponível no sítio do GitHub para início rápido em Allegro. Basicamente trata-se da linguagem C com uso da biblioteca Allegro.

Primeiro adicionamos ao módulo os arquivos de cabeçalho (contendo definições e declarações de protótipos, com a extensão .h de header) com as diretivas #include.

As inicializações se referem à sequência de eventos de teclado, janela, temporizador e à fonte do texto.

Em seguida, há a estrutura principal, de repetição com while, envolvendo estruturas condicionais com if.

E, em seguida, a finalização, que é a limpeza dos recursos criados na inicialização e o retorno ao sistema operacional.

  • Reflexão

Viva como se você fosse morrer amanhã. Aprenda como se fosse viver para sempre.

Perl – Operadores – parte II

Este exemplo ilustra o uso de operadores relacionais e lógicos em Perl.

  • Design-time
#solicita 2 números e realiza operações relacionais e lógicas
#usa operador ternário: (operação relacional ou lógica) ? 1 : 0

print "Informe o primeiro número: ";
chomp($n1 = <STDIN>);
print "Informe o segundo número: ";
chomp($n2 = <STDIN>);
print "\n\t\tOPERAÇÕES RELACIONAIS\n\n";

print "Igual \t\t $n1 == $n2 \t", $n1 == $n2 ? 1 : 0, "\n";
print "Diferente \t $n1 != $n2 \t", $n1 != $n2 ? 1 : 0, "\n";
print "Maior \t\t $n1 > $n2 \t\t", $n1 > $n2 ? 1 : 0, "\n";
print "Maior ou igual \t $n1 >= $n2 \t", $n1 >= $n2 ? 1 : 0, "\n";
print "Menor \t\t $n1 < $n2 \t\t", $n1 < $n2 ? 1 : 0, "\n";
print "Menor ou igual \t $n1 <= $n2 \t", $n1 <= $n2 ? 1 : 0, "\n";
print "Comparação \t $n1 <=> $n2 \t", $n1 <=> $n2, "\n";

print "\n\t\tOPERAÇÕES LÓGICAS\n\n";

print "E\t($n1 == $n2) && ($n1 == $n2) \t", ($n1 == $n2) && ($n1 == $n2) ? 1 : 0, "\n";
print "\t($n1 == $n2) && ($n1 != $n2) \t", ($n1 == $n2) && ($n1 != $n2) ? 1 : 0, "\n";
print "\t($n1 != $n2) && ($n1 == $n2) \t", ($n1 != $n2) && ($n1 == $n2) ? 1 : 0, "\n";
print "\t($n1 != $n2) && ($n1 != $n2) \t", ($n1 != $n2) && ($n1 != $n2) ? 1 : 0, "\n\n";

print "Ou\t($n1 == $n2) || ($n1 == $n2) \t", ($n1 == $n2) || ($n1 == $n2) ? 1 : 0, "\n";
print "\t($n1 == $n2) || ($n1 != $n2) \t", ($n1 == $n2) || ($n1 != $n2) ? 1 : 0, "\n";
print "\t($n1 != $n2) || ($n1 == $n2) \t", ($n1 != $n2) || ($n1 == $n2) ? 1 : 0, "\n";
print "\t($n1 != $n2) || ($n1 != $n2) \t", ($n1 != $n2) || ($n1 != $n2) ? 1 : 0, "\n\n";

print "Não\t!($n1 == $n2) \t\t", !($n1 == $n2) ? 1 : 0, "\n";
print "\t!($n1 != $n2) \t\t", !($n1 != $n2) ? 1 : 0, "\n\n";
  • Runtime
Perl rodando em Ubuntu 22.04 (Jammy Jellyfish), captura de tela com Peek
  • Sintaxe

Aqui basicamente temos duas novidades: o operador ternário e o operador de comparação.

Como Perl não faz diferença entre as variáveis escalares 0, “0” e “”, para deixar claro o resultado da operação, tanto relacional e como lógica, optamos por empregar o operador ternário

condição ? valor se condição é verdadeira (1) : valor se condição é falsa (0)

O operador ternário só não foi necessário na linha 16 da listagem acima porque o operador de comparação (<=>), também conhecido por spaceship, entre dois operandos retorna o valor

1 se o primeiro operando for maior que o segundo,

0 se ambos operandos forem iguais, e

-1 se o primeiro operando for menor que o segundo.

  • Reflexão

Suas escolhas dizem muito mais a respeito de você do que delas próprias. Palavras são apenas palavras, e podem ser apenas dissimulações. Só as atitudes e as escolhas são de fato eloquentes.

Hoje, 2 de outubro de 2022, não acaba, mas começa o fim do nazifascismo miliciano. Poderão esmagar uma, muitas ou talvez até todas as flores, mas não conseguirão impedir a chegada da primavera.