quarta-feira, 22 de agosto de 2007

Eu coleciono registros. E você ?

Você coleciona tampinhas, latinhas de alumínio, selos ou carrinhos em miniatura ? Aprenda a criar coleções de registros dos seus arquivos indexados e comece a pensar mais em objetos:

Na class-control, defina as classes que serão utilizadas:

class-control.
....CharacterArray is class "chararry"
....OrderedCollection is class "ordrdcll".

Vamos tomar como exemplo um registro de um arquivo de bancos, com código e nome do banco. Mas você pode adaptar esse exemplo com qualquer outra FD:

FD CadastroDeBancos.
01 RegistroDoBanco.
...02 CodigoDoBanco pic 9(03).
...02 NomeDoBanco pic x(60).

Na working-storage section, defina as seguintes variáveis:

77 umaColecao object reference value null.
77 umObjeto object reference value null.
77 wsTamanho pic 9(09) comp-5 value zeros.
77 wsQuantidade pic 9(09) comp-5 value zeros.
77 wsPosicao pic 9(09) comp-5 value zeros.

A primeira coisa a ser feita é criar uma coleção para armazenar todos os objetos contendo os registros lidos. Essa coleção é criada a partir do método "OfReferences" da classe OrderedCollection:

move 0 to wsQuantidade
invoke OrderedCollection "ofReferences" using wsQuantidade
returning umaColecao

Agora, digamos que exista um procedimento em seu programa que leia o arquivo de bancos, registro a registro, através de um "read ArquivoDeBancos next". A cada registro lido, você pode criar então um objeto do tipo CharacterArray, através do método "WithLengthValue". Esse método recebe como parâmetros, o tamanho e o conteúdo do objeto que se deseja criar. Em nosso exemplo, vamos passar o tamanho do registro de bancos e o seu conteúdo:

move length of RegistroDoBanco to wsTamanho
invoke CharacterArray "withLengthValue"
using wsTamanho RegistroDoBanco returning umObjeto

Em seguida, armazenamos o objeto criado utilizando o método "Add". Esse método armazena os objetos na coleção, na mesma ordem em que são adicionados: o primeiro fica na primeira posição da coleção, o segundo na segunda posição, e assim por diante:

invoke umaColecao "add" using umObjeto

Isso deve ser feito a cada registro lido do arquivo. Ao terminar a leitura do arquivo, você terá o objeto umaColecao contendo diversos objetos, cada um deles com o conteúdo de um registro lido do arquivo de bancos. Uma aplicação prática para a utilização desse recurso seria criar rotinas que gerem essas coleções baseadas em determinados critérios. Em uma rotina que manipulasse um arquivo de empresas poderiam ser criadas coleções de empresas de um determinado tipo: pessoa jurídica, por exemplo. Em uma rotina que manipulasse um arquivo de funcionários poderiam ser criadas coleções com funcionários ativos, outra com funcionários desligados.

Quando um programa recebe uma coleção de objetos, ele pode saber a quantidade de objetos na coleção através do método "size":

invoke umaColecao "size" returning wsQuantidade

Se você deseja pegar um objeto em uma posição específica dentro da coleção, pode se utilizar o método "at":

move 5 to wsPosicao
invoke umaColecao "at" using wsPosicao
returning umObjeto


No exemplo acima, recuperamos o objeto na quinta posição da coleção. Note que se a coleção não contém o objeto na posição especificada, uma mensagem de erro será retornada. Se a coleção contém 5 objetos, você não pode tentar recuperar um objeto na posição 9, por exemplo.

Depois de recuperado um objeto, você pode retornar seu conteúdo novamente em uma variável. Em nosso exemplo, vamos recuperar o conteúdo diretamente no registro de bancos. Para retornar o conteúdo de um objeto, utilize o método "getValue":

invoke umObjeto "getValue" returning RegistroDoBanco

Atente para um detalhe: a variável que receberá o conteúdo de um objeto deve ter tamanho suficiente para armazenar a informação. Caso o tamanho não seja suficiente, você pode ter problemas de violação de memória.

Agora é só usar a criatividade e criar as suas próprias coleções de registros.

4 comentários:

NeoPravda disse...

acho que seria mais útil se fosse criado um engine para manipular arquivos de dados dinamicamente. seria um meio termo entre os arquivos isam de caráter imutáveis do cobol e um bd relacional. com poucos arquivos poderiamos criar tabelas e suas colunas de forma dinâmica, ainda que fosse necessário varrer os "registros" como se faz hoje no cobol. destaforma uma collection conteria dados ao invés de uma string que precisa ser aplicada a um item de grupo para se recuperar os itens de dado....se tiver interesse na idéia, me contacte (emersonlopes@gmail.com).

PS: este seria um projeto tipo POC (Proof of Concept). Não estou interessado em comercialização ou algo assim.os fontes podem ficar contigo...

PS2: o netexpress suporta reflection?

Alexandre Cortez. disse...

caro amigo Emerson...

o exemplo que mostrei nesse post, apenas insinua uma das mais diversas formas de se trabalhar com objetos contendo sequência de caracteres... conheço amigos desenvolvedores que utilizam outras formas de gerenciamento dessas informações... resolvi utilizar registros de arquivos indexados como exemplo, apenas para plantar uma sementinha no pensamentos dos desenvolvedores que utilizam a COBOL como ferramenta... infelizmente, nem todos tem acesso a programação orientada ao objeto, e o objetivo desse modesto blog é justamente esse: "acender uma luz" para que os desenvolvedores possam explorar novas técnicas novos recursos que a ferramenta oferece... quanto ao assunto "reflection", foge aos meus conhecimentos o termo utilizado... não saberia lhe responder... para terminar, agradeceria se você disponibilizasse o "know-how" que possui para que eu possa divulgá-lo em nossas listas de discussão... todo o crédito será dado a você, pois vou fazer questão de divulgar a sua colaboração sobre o assunto... agradeço a sua visita ao blog... abraços...

NeoPravda disse...

Alexandre,

seu blog é um dos poucos blogs sobre cobol que vale a pena ler. a maioria dos desenvolvedores cobol parou no tempo e se recusa a abrir a mente e abraçar novas tecnologias (as exceções podem ser contadas com os dedos da mão).

Tendo dito isto, :), reflection é a capacidade da linguagem pesquisar em tempo de execução a estrutura de um objeto (não o conteúdo!). Assim podemos pegar um objeto qualquer, descobrir quais são os métodos que ele implementa, parâmetros de entrada e saída, tipo do parâmetro etc. A primeira vista pode parecer algo sem sentido se durante o desenvolvimento sabemos qual objeto estamos instanciando. Ocorre que muitas vezes precisamos carregar uma classe sem que a mesma seja conhecida em tempo de execução (ex: pattern provider). Isto dá uma enorme flexibilidade na hora de escrever plugins, por exemplo. Claro que reflection tem um custo alto de processamento, mas o uso de técnicas de cache e mesmo geração de código dinamicamente (emitindo um novo objeto em tempo de execução) minimizam ou eliminam o problema.

Penso que as vezes estamos só chapinhando no raso com OO. Tem todo um oceano à frente a ser explorado...

[]s, Emerson

PS: Se Netexpress suporta .net, certamente suporta reflection (System.Reflection)...ou pelo menos deveria...

Alexandre Cortez. disse...

Tenho que agradecer aos seus elogios, Emerson. O NetAlexpress é feito com muito carinho, e os útlimos emails que recebi de amigos desenvolvedores só estão confirmando que o meu objetivo foi alcançado. Em relação ao assunto "reflection", em minhas pesquisas recentes tenho trabalhado com uma classe disponível no NetExpress que oferece recursos bem próximos ao tema. A classe chama-se Behavior e com ela posso saber quais os métodos que uma determinada classe possui, além de saber informações sobre as instâncias criadas pela mesma, ou se a mesma responde por um determinado método. As pesquisas são recentes, mas serão muito importantes se me permitirem descobrir informações como as que você cita em seu último comentário. Seria realmente interessante conhecer a estrutura de uma classe, seus métodos e parâmetros, sem que a mesma pertença a uma biblioteca de classes conhecida. Eu não uso o Microfocus na plataforma .NET, mas acredito que haja algo parecido sim, na versão 5.0 do compilador. Fique à vontade, Emerson, para continuar a colaborar com o blog, pois seu conhecimento, sem dúvida, será também de muita valia a todos que aqui vêm em busca de informações.