Conversão 'Redefines' (natural) para Java

Olá…
Estou fazendo uma conversão da linguagem Natural, para Java e me deparei com o Redefines da linguagem. Queria debater com vocês, qual a melhor estratégia que posso seguir para adequar meu código a essa função.
O redefine pega uma variavel e divide o endereço de memória dela em varias partes de acordo com minha necessidade, por exemplo, pego uma variavel chamada Data com 8 caracteres, divido em 3 variaveis, dia (2 caracteres), mes(2 caracteres) e ano (4 caracteres). Se eu defino uma data (05082022), essas variaveis também são definidas. dia(05), mes(08) e ano (2022)… Até ai eu poderia fazer com substring, sem problema. O problema é que se eu alterar o ano por exemplo, altera o valor da Data também, e eu não quero ter que ficar vendo se eu alterar uma variavel, tenho que alterar outra também. Minha ideia é fazer um setData(String data) e dentro desse metodo, ja altero as outras variaveis, e criar um setDia(String dia), setMes(String mes) e setAno(String ano), e altero também o valor da variavel Data.

Me desculpem o tamanho do texto, mas não sei explicar resumidamente.

Eu sinceramente não entendi o que vc precisa. Que linguagem é essa chamada “natural”? Vc está falando de linguagens naturais como um todo? Vc menciona esse “redefines” e me dá a ideia que é uma instrução dessa tal linguagem. Sei lá, tá faltando coisa ai no seu texto para explicar direito o que vc quer fazer. Aliás, pra começo de conversa, vc não tem esse controle fino em relação à memória em Java.

Quanto ao seu “problema” com datas, não faz muito sentido representar uma data usando 8 caracteres. Em Java cada caractere ocupa 16 bits (2 bytes). Vc estaria usando 16 bytes para representar uma data, ao passo que com um long você consegue representar uma data e hora inteira (milissegundo, segundo, minuto, hora, dia, mês e ano) usando 8 bytes ou então usando um inteiro para cada componente (dia, mês e ano), totalizando 12 bytes.

Explica melhor aí, não se preocupe em ser prolixo. É melhor escrever bastante e se fazer entender do que escrever pouco de forma confusa.

Acho que você está se referindo à linguagem Natural usada com o banco de dados Adabas, nunca tentei aprender essa linguagem, mas o Java possui as classes LocalDate e LocalDateTime para armazenar e manipular datas, e datas com horários respectivamente, só faria sentido dividir a data em diferentes variáveis se você fosse usar algum tipo primitivo do java para processar bilhões de datas de forma mais rápida.

Já vi REDEFINES na linguagem COBOL. É COBOL que vc tah usando?

Natural é uma linguagem de baixa plataforma (Mainframe), usada junto com banco de dados Adabas.
Redefine é uma instrução da linguagem sim, serve justamente pra fazer o que eu descrevi.
O grande problema disso, é que usei data como exemplo, mas são vários tipos e casos que usa essa instrução. Então precisa ser algo genérico, por isso usei caracteres, pois não quebra os dados como por exemplo se tivesse um inteiro com zeros a esquerda, sendo string continuaria com esses zeros.

não, é Natural, porém faz a mesma coisa que em Cobol.
São linguagens parecidas.

Ah sim, essa é aquela que eh usada para criar as “interfaces” do COBOL?

Achei essa referência: How to deal with COBOL REDEFINES? - Knowledge base - Software AG Tech Community & Forums

COBOL REDEFINES

REDEFINES allow the same memory area to be described by different layouts. Example:

02 VEHICLES-DATA                PIC X(4954).
02 VEHICLES-DETAILS REDEFINES VEHICLES-DATA.
   03 MODEL                     PIC X(20).
   03 MANUFACTURER              PIC X(20).
   . . . 
02 VEHICLES-LIST REDEFINES VEHICLES-DATA.
   03 VEHICLES-COUNT            PIC 9(8) BINARY.
   03 VEHICLES OCCURS 99.
      03 IDENT                  PIC X(10).
. . . 

Olhando para o exemplo, é como se duas estruturas diferentes (VEHICLES-DETAILS e VEHICLES-LIST) fossem tratadas ambas como sendo do tipo VEHICLES-DATA. Se for isso mesmo (e se for para chutar um palpite), será que seria equivalente à herança?

Bom dia.

Pior que não, Lucas.
Deixa eu tentar explicar melhor o que o Redefine faz.

Vamos supor que eu tenha definido uma variável chamada CPF, com um alfanumérico de 11 dígitos.
faço um Redefine dele… ficaria assim

01 #CPF              (A011)
01 REDEFINE #CPF
    02 #PARTE1   (A003)
    02 #PARTE2   (A003)
    02 #PARTE3   (A003)
    02 #PARTE4   (A002)

Assim consigo manipular 5 variaveis, que são do mesmo endereço de memória, por exemplo, se eu digo que CPF = “12345678901”, automaGicamente, as outras variáveis assumem os valores
PARTE1 = 123
PARTE2 = 456
PARTE3 = 789
PARTE4 = 01

se fosse só esse caso, era tranquilo de resolver, o problema é que posso também, alterar as outras variaveis, o que afeta diretamente a variável #CPF… Por exemplo, CPF esta com o valor “12345678901”, eu vou e altero a variavel #PARTE4 pra “XX”, a variavel CPF assumirá o valor “123456789XX”.

Não se prendam ao tipo de dados, ou “Nossa, pra que voce esta quebrando um CPF assim?”. Não é esse o ponto, tentei só explicar melhor o que preciso converter pra Java.

Se entendi o caso, acho que você não vai encontrar nada nativo no Java equivalente à isso, então uma opção é criar uma classe para isso. Essa classe poderia armazenar ao menos 2 informações: valor/ conteúdo (string) e expressao/regex, que seria responsável por dividir a string valor conforme necessário usando split. Não está muito claro pra mim qual a necessidade de ter as informações separadas (se é para validação ou outros processos), mas se for necessário, você pode ter um array para o conteúdo separado pelo split. Ficaria algo como:

class Redefine{
  private String conteudo; // contém o valor íntegro
  private String expressao; // contém a expressão/regex que divide conteúdo
  private String[] conteudoSplit; // vai conter as partes

  public Redefine(string c, string e){
    expressao = e;
    setConteudo(c);
  }

  public void setConteudo(String c){
    conteudo = c;
    conteudoSplit = c.split(expressao);
  }

  public String getPart(int index){
    // obs: ter tratamento de exceção IndexOutOfBounds aqui, ou mesmo disparar a exceção
    return conteudoSplit[index];
  }
}

Pode haver métodos auxiliares (ex: retornar quantidade de partes em que o conteúdo foi dividido em um getPartCount(), ou permitir mudar a expressão com setExpressao()), vai da sua necessidade.

Obviamente, essa é uma simplificação, pois não tenho os detalhes do problema que você quer resolver.
Estou enferrujado demais no Java pra entrar nos detalhes específicos, mas espero que isso clareie um pouco o caso.

Talvez haja alguma biblioteca de terceiros com funcionalidades similares, mas teria que procurar por aí (GitHub e afins).

Abraço.

1 curtida

Minha melhor ideia por enquanto foi fazer isso…

String cpf;
String parte1;
String parte2;
String parte3;
String parte4;
	
private void setCPF(String valor) {
	this.cpf = valor;
		
	this.parte1 = cpf.substring(0, 3);
	this.parte2 = cpf.substring(3, 6);
	this.parte3 = cpf.substring(6, 9);
	this.parte4 = cpf.substring(9, 11);
}
	
private void setParte1(String valor) {
	String altera = this.cpf.substring(0, 3);
	String alterado = this.cpf.replaceAll(altera, valor);
		
	setCPF(alterado);
}
	
private void setParte2(String valor) {
	String altera = this.cpf.substring(3, 6);
	String alterado = this.cpf.replaceAll(altera, valor);
	
	setCPF(alterado);
}
	
private void setParte3(String valor) {
	String altera = this.cpf.substring(6, 9);
	String alterado = this.cpf.replaceAll(altera, valor);
	
	setCPF(alterado);
}
	
private void setParte4(String valor) {
	String altera = this.cpf.substring(9, 11);
	String alterado = this.cpf.replaceAll(altera, valor);
	
	setCPF(alterado);
}

Pode haver uma solução mais avançada pra isso, mas testando aqui, isso atende as minhas necessidades. Porém, se houver alguma solução mais otimizada, mais facil, aceito sugestões.