Class/Record Helpers, a saga continua!

E ae galera! O Bruto tá de volta. No post anterior, eu disse que, a partir do Delphi XE3 é possível utilizar record helpers para expandir tipos nativos. E o melhor, a Embarcadero já fez grande parte do serviço pra gente. Vamos começar a explorar essa maravilha: Inclua no seu Uses a unit SysUtils, se ela já não estiver lá.

Nessa unit, nós temos os seguintes helpers:

TStringHelper, TSingleHelper, TDoubleHelper, TExtendedHelper, TByteHelper, TShortIntHelper, 
TSmallIntHelper, TWordHelper, TCardinalHelper, TIntegerHelper, TInt64Helper, TUInt64Helper, 
TNativeIntHelper, TNativeUIntHelper, TBooleanHelper, TByteBoolHelper, TWordBoolHelper, 
TLongBoolHelper

Ufa… acabou. Vou explicar alguns helpers, algumas funções que eu acho mais legais. O resto… o resto é muita coisa… peguem um projetinho novo, façam um códigos ai, estudem um pouco… Faz bem e não cai a mão não viu? Vamos lá:

procedure TForm1.Teste;
var 
  str,tmp: String;
  rr: TArray<string>;
  i: Integer;
Begin
  str := 'Teste de string, 123 testando!';
  If str.contains('de') then
    Showmessage('str contem “de”');
  rr := str.split([',']);
  showmessage(rr[0]+' ---- '+rr[1].QuotedString);
  showMessage(str.ToLower.IndexOf('t').ToString+' --- '+str.ToLower.LastIndexOf('t').ToString );
  showMessage(str.Replace('e','I'));
  showmessage(str.Substring(6,9));
  tmp := '';
  for I := str.Length-1 downto 0 do
    tmp := tmp + str.Chars[i];
  showmessage(tmp);
  showMessage('Blog do Rodrigo Mourao'.CountChar('o').ToString);
End;

Confuso né? Mas calma, vamos começar a estripar esse código. Começamos pela declaração de variáveis (linhas 3 a 5): duas Strings, uma Integer e uma Array genérica de strings. Se não sabe o que é uma array genérica, relaxa, num próximo post eu vou explicar. Por enquanto, para o que precisamos agora, ela é como se fosse uma array normal de strings Ahn, detalhe: para funcionar, coloca no uses System.Generics.Collections. Joguei o valor “Teste de string, 123 testando!” na nossa variável str (linha 7).

A primeira coisa que você deve ter notado é que eu usei a variável str, de um tipo nativo (string), como se fosse uma classe, com métodos (linha 8). Essa mágica é o Record Helper em ação. Antes de começarmos, vamos combinar uma coisa pra não rolar confusão: vou chamar de “Self” a variável ou constante que está chamando o método. Em “str.contains(‘de’)”, str seria Self, contains é método e ‘de’ é parâmetro do método contains (linhas 8 e 9). Agora vamos sentar a madeira:

  If str.contains('de') then
    Showmessage('str contem “de”');

O método “contains” recebe como parâmetro uma string, e verifica se ela está contida na Self, retornando um boolean. Você vai dizer: “Porra bruto, e exatamente a mesma coisa do Pos > 0”. Sim é, mas em uma linha só, retornando boolean e prontinho para ser usado num if. Muito mais prático, né ? Como você viu no resultado, a string “de” está contida na minha frase “Teste de string, 123 testando!”. Agora note o código abaixo:

  rr := str.split([',']);
  showmessage(rr[0]+' ---- '+rr[1].QuotedString);

Aqui as coisas ficam mais legais, se você veio do PHP já é chegado na função explode. Para quem não é, o método Split transforma a Self em um array, desmembrando-a nos pontos em que ela acha os caracteres passados como parâmetro. Se você for esperto já percebeu que o método Split recebe como parâmetro um array de char então você pode quebrar a sua Self em pontos diversos (linha 1). Aliás, o método Split tem várias outras formas, explore-as. Ahhhh! E tem mais um método ai nesse exemplo: o QuotedString, ele coloca a string entre aspas e se você pensou: “perfeita pra SQL”, acertou em cheio. Nesse exemplo, eu cortei a nossa string na vírgula (linha 1), ficaram duas metades: “Teste de string” e ” 123 testando!”. Essa última eu coloquei entre aspas para exibir no showmessage (linha 2). Note então o código abaixo:

  ShowMessage(str.ToLower.IndexOf('t').ToString+' --- '+str.ToLower.LastIndexOf('t').ToString );

Temos aqui outra coisa bem legal, métodos encadeados. Parece uma cama de gato, mas depois que você entende fica genial. O método ToLower devolve a Self toda em minúsculo, nesse resultado, que também é uma string, aplicamos o método IndexOf que me retorna o primeiro índice do parâmetro na Self, sim exatamente igual ao Pos. Esse retorno é um Integer, que para ser usado no showmessage tem que ser convertido para string e faço isso com o método ToString que é um helper para Integer. Também aparece nesse exemplo o método LastIndexOf, que retorna o índice da última aparição do parâmetro na Self. No nosso exemplo o primeiro ‘t’ está na posição 0 (zero) e o último ‘t’ está na posição 24. Ah, um detalhe: diferentemente da função Pos, o IndexOf (e todas as outras helpers de string) a string começa na posição 0 (zero) e não 1. Seguindo em frente:

ShowMessage(str.Replace('e','I'));

Replace troca na Self todas as ocorrências do primeiro parâmetro, com o segundo parâmetro. No exemplo acima, trocamos todos os ‘e’ da frase “Teste de string, 123 testando!” por ‘I’. Mais um:

showmessage(str.Substring(6,9));

Substring funciona exatamente como como copy, ele corta um pedaço da Self, iniciando no primeiro parâmetro e com a quantidade de caracteres do segundo parâmetro. Novamente frisando que no caso dos helpers, o índice começa do zero. No nosso exemplo da frase “Teste de string, 123 testando!”, copiamos da sexta posição, nove caracteres. Agora note:

  tmp := '';
  for I := str.Length-1 downto 0 do
    tmp := tmp + str.Chars[i];
  showmessage(tmp);

A função Chars acessa diretamente o caractere na posição indicada, começa de zero também. No exemplo usei um laço for downto (ao contrário) para inverter a string, acessando cada caractere individualmente. Antes de continuar, você deve tá se perguntando: “A grande parte desses helpers, só faz a mesma coisa que as funções que eu já uso hoje em dia. Porque deveria usá-los? ”. Cara em alguns casos é uma preferência pessoal. Acho mais legal ir chamando os métodos um depois do outro, por pontos, do que ir enfiando uma função dentro da outra, dentro da outra (Pode chamar de viadagem, se isso te deixa mais feliz).

Mas em outros casos, como no indexof, substring, chars, que ele começa a contar do zero ao invés de 1, é melhor usá-las, pois se você um dia você for usar seu código no Firemonkey, não vai dar zica. O compilador dele, seja pra Win32, Android ou iOS, sempre conta a string do zero. Então, se você começar a contar a sua do zero também, vai ser só apertar F9 e ser feliz. E por último, e não menos legal:

  ShowMessage('Blog do Rodrigo Mourão'.CountChar('o').ToString);

Podemos usar os métodos do helper diretamente em constantes, como se elas fossem classes. Usei na constante ‘Blog do Rodrigo Mourão’ o método CountChar, que conta a quantidade de um determinado caractere na Self. Essa contagem (que retorna um Integer) eu apliquei o helper ToString para usar o showmessage. Bem galera, eu sei que prometi falar de mais alguns helpers e mostrar os que eu desenvolvi, mas só com esses de strings, o post já ficou gigante. Então vou parar por aqui, porque eu não sou de ferro também e no próximo post falo de mais alguns helpers da Embarcadero e passo os fontes dos meus.

Bons estudos, até a próxima e coice do bruto!