SAP – Recursividade em ABAP ???

Leitores,

O conteúdo deste post foi concedido pelo blog ABAP101, estamos compartilhando o mesmo devido seu conteúdo ser extraordinário.Equipe ABAP 101 está de parabéns.

Uma das técnicas de programação mais incompreendida e evitada, também é umas das mais poderosas, a Recursividade.

Nesse texto eu vou resolver um problema muito simples usando recursividade, exponenciação.

Exponenciação

De acordo com  a Wikipédia:

Exponenciação ou potenciação é uma operação matemática, escrita como An, envolvendo dois números: abase a e o expoente n. Quando n é um número natural maior do que 1, a potência an indica a multiplicação da base a por ela mesma tantas vezes quanto indicar o expoente n.

A fórmula da exponenciação é simples e por isso considero um exemplo legal para mostrar a recursividade em prática.

Exponenciação Usando Recursividade

No ABAP você pode usar o operador ** para fazer a exponenciação e resolver todo o problema em uma linha (veja no programa abaixo), mas esse post não é sobre exponenciação, mas recursividade.

Novamente da Wikipédia:

 A recursão é o processo pelo qual passa um certo procedimento quando um dos passos do procedimento em questão envolve a repetição completa deste mesmo procedimento. Um procedimento que se utiliza da recursão é dito recursivo. Também é dito recursivo qualquer objeto que seja resultado de um procedimento recursivo.

Em ABAP claro significa uma subrotina (form, módulo de função ou método) que efetua uma chamada dela mesmo.

Por exemplo, usando a recursão para resolver um problema de potência, farei com que o método EXECUTE_EXPONENTIATION( ) seja chamado inúmeras vezes por ele mesmo, de acordo com o expoente passado para ele como parâmetro.

Também poderíamos usar a estrutura de loop DO n TIMES … ENDDO, mas aí não seria recursão.

Veja o programa abaixo:

ZABAP101_RECURSION

*&———————————————————————*
*& Report ZABAP101_RECURSION
*&
*&———————————————————————*
*&
*&
*&———————————————————————*
REPORT zabap101_recursion.
*———————————————————————-*
* CLASS lcl_math DEFINITION
*———————————————————————-*
*
*———————————————————————-*
CLASS lcl_math DEFINITION.
  PUBLIC SECTION.
    METHODS execute_exponentiation
              IMPORTING
                base TYPE i
                expoent TYPE i
              RETURNING value(re_power) TYPE i.
  PRIVATE SECTION.
    DATA: interaction TYPE i,
          power TYPE i VALUE 1.
ENDCLASS. “lcl_math DEFINITION
*———————————————————————-*
* CLASS lcl_math IMPLEMENTATION
*———————————————————————-*
*
*———————————————————————-*
CLASS lcl_math IMPLEMENTATION.
  METHOD execute_exponentiation.
    ADD 1 TO interaction.
    IF interaction <= expoent.
      power = me->execute_exponentiation( base = base
                                          expoent = expoent ).
      MULTIPLY power BY base.
    ENDIF.
    re_power = power.
  ENDMETHOD. “execute_exponentiation
ENDCLASS. “lcl_math IMPLEMENTATION
DATA: r_exp TYPE REF TO lcl_math,
      v_power TYPE i.
PARAMETERS: p_base TYPE i DEFAULT 2,
            p_exp TYPE i DEFAULT 3,
            p_rec AS CHECKBOX.
INITIALIZATION.
  CREATE OBJECT r_exp.
START-OF-SELECTION.
  IF p_rec = ‘X’.
    v_power = r_exp->execute_exponentiation( base = p_base
                                             expoent = p_exp ).
  ELSE.
    v_power = p_base ** p_exp.
  ENDIF.
  WRITE: / ‘Power: ‘, v_power.

Execute esse programa no modo debug e veja a pilha de chamada. Veja que o método se repete várias vezes indicando que ele fora chamado de dentro dele mesmo, caracterizando uma recursividade:

Pilha de chamadas do método EXECUTE_EXPONENTIATION( ) – Recursividade

A primeira linha do método incrementa o atributo INTERECTION, daí o método chama ele mesmo se a interação for menor ou igual ao expoente. Com isso a pilha (stack) vai sendo adicionada a cada nova chamada até que o número máximo de iterações (expoente) seja alcançado.

A pilha pára de ser incrementada e o restante do método começa a ser chamado, a partir do item da pilha mais novo (LIFO, Last In First Out), onde finalmente a multiplicação é feita e sendo acumulada no atributo POWER.

Explosão de Lista Técnica

Existem problemas em que a recursividade é quase que obrigatória, no caso da chamada explosão de lista técnica.

Imagine que você precise saber o custo de algum material que é composto por outros materiais, como por exemplo um notebook.

Um notebook pode ser um materia formado por teclado, display LCD, HD, placa-mãe, memórias, carcaça etc.

O teclado é formado por uma base, uma tecla Q, outra W, outra E, outra R, outra T etc.

Um HD é formado por um conjundo de discos magnéticos, placa de controle e sistema de leitura,

Um sistema de leitura é formado por um braço de leitura, cabeçote de leitura e placa de leitura.

E assim por diante.

Se eu tivesse uma rotina que dado um material ele me retornasse uma lista de materais que formam esse material, eu precisaria chamar essa rotina n vezes, conforme eu fosse “desmontando” ou “explodindo” meu material.

Dessa maneira a haveria a recursividade como exemplificado no exemplo do notebook, resolvendo o problema muito rapidamente.

Claro que nem tudo são flores. Depurar um programa que usa recursividade é muito trabalhoso, bem como entender a recursividade que outra pessoa desenvolveu. Isso faz com que a recursão seja evitada, mas em alguns casos é a melhor forma de resolver um problema.

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s