Prisma - Linguagem de programação

Prisma-1.0 => Publique aqui => Tópico iniciado por: adalberto online Junho 04, 2015, 09:40:53 AM

Título: orientação a objetos, simples exemplo
Enviado por: adalberto online Junho 04, 2015, 09:40:53 AM
Orientação em objetos é um paradigma difícil de se introduzir no mundo da programação. Atualmente temos diversas linguagens que suportam esse mecanismo como o C++, Python, Ruby etc. Outras que forçam unicamente esse tipo de programação como Java, por exemplo.

Prisma como uma modificação do código original Lua, não tem a orientação a objetos nativamente, mas tem os mecanismos necessários para se chegar a ela. Para tanto foi implementada uma biblioteca com a classe primordial para criar as outras e com um método principal para derivar os objetos.

Pense em poo (programação orientada a objetos) como uma organização diferente. As funções (como imprima(), leia() tente() convstring() etc) e dados ( como: peso, altura, comprimento, gastos, saldo, preço, cliente_a , cliente_b etc) não ficam avulsas como na programação estruturada (blocos de funções e estruturas de dados).
Mas ficam empacotados em uma única variável chamada classe, da qual podemos declarar novas variáveis que automaticamente herdam as funções e dados da classe pai.

Bom chega de bla bla bla, vamos ao exemplo para facilitar:


                                               Um exemplo bem simples primeiro:




//exemplo classe simples:
//importando a lib "classe"
inclua'classe';

//note que a funcao que cria classe é inicial maiuscula "Classe()";

//criando uma classe com dados em valores padrões:
pessoa = Classe{nome = 'nao definido' , idade = 'nao definido' } ; //nova classe chamada 'pessoa'
funcao pessoa.mostre_dados( este )
     poe'---------------------------------------------------------------';
     imprima(este.nome);
     imprima(este.idade);
fim

//quando usamos dois pontos no método
//não precisamos passar explicitamente o parâmetro este
//fica subentendido:
funcao pessoa:denome( nome )
     este.nome = nome;
fim

funcao pessoa:deidade( idade )
    este.idade = idade;
fim

maria = pessoa:novo{  };
maria:mostre_dados();
maria:denome('Maria'); //agora damos um nome
maria:mostre_dados(); //mas idade está nulo ainda

//criando um novo objeto pessoa com dados
// já passados
joao = pessoa:novo{ nome = 'Joao' , idade = 28 };
joao:mostre_dados();



Veja a saída (Ubuntu 14.04):
(http://www.linguagemprisma.net/images/ooSimples.png)



                                                                     Um mais avançado:



//Para criarmos classes e depois objetos em Prisma precisamos incluir a biblioteca 'classe':
inclua'classe';

//criando uma nova classe chamada conta_bancaria:
conta = Classe{
nome = '' , //dado nome do usuario da conta
saldo = 0, //definindo um saldo padrão = zero

despositar = funcao( este , n ) 
     este.saldo = este.saldo + n; //somando o novo deposito ao saldo atual;
fim ;
sacar = funcao( este , n  )
   este.saldo = este.saldo - n ; //subtraindo do saldo atual
fim ;
poupanca = 0 ;  //definindo valor da poupanca

transf_para_poupanca = funcao(este , n )
       imprima('\n' , sis.data() , '\nDeposito da conta corrente para poupanca, valor: ' , n , '\n' );
     este.saldo = este.saldo - n; //tirando da conta corrente
    este.poupanca = este.poupanca + n; //colocando na poupanca
fim ;

transf_para_conta = funcao ( este , n )
   imprima('\n' , sis.data() , '\nDeposito da poupanca para conta, valor: ' , n , '\n' );
    este.poupanca = este.poupanca - n;
    este.saldo = este.saldo + n;
fim  ; //nunca se esqueça de separar por ponto e vírgula ou vírgula

mostre_nome = funcao(este) imprima('\nNome :' , este.nome, '\n') fim;
mostre_saldo = funcao( este )  imprima( 'Saldo conta corrente :' , este.saldo, '\n' ) fim ;
mostre_poupanca = funcao( este ) imprima('Poupanca :' , este.poupanca, '\n' ) fim

}


//feito a classe conta podemos fazer objetos a partir dela como o metodo novo

conta_padaria = conta:novo({nome = 'Conta padaria'});
//se preferir pode descartar os parênteses quando passar uma tabela.
conta_padaria:mostre_nome();
conta_padaria:mostre_saldo();
conta_padaria:mostre_poupanca();

//voce pode passar uma tabela redefinindo os dados:
conta_pessoal = conta:novo{nome = 'Paulo-conta' , saldo = 250.00 };
conta_pessoal:mostre_nome(); //imprime o nome
conta_pessoal:mostre_saldo(); //imprime o saldo conta corrente
conta_pessoal:mostre_poupanca(); //imprime saldo poupanca
conta_pessoal:despositar( 1000.00 ); //deposita
conta_pessoal:mostre_saldo(); //imprime saldo
conta_pessoal:transf_para_poupanca( 250.00 ); //transfere para poupanca
conta_pessoal:mostre_saldo();  //imprime saldo
conta_pessoal:mostre_poupanca(); //imprime poupanca


Note que:

*este* é uma palavra reservada que simboliza a tabela do próprio objeto passado como parâmetro 'este';
São usados dois pontos *:* para acessar um método de um objeto:   conta_pessoal:mostre_poupanca();


                                                             HERANÇA

Muitas vezes queremos construir uma nova classe, mas não do zero, seria bom pegar os dados e os métodos emprestados de uma classe já existente, isso se chama herança, pois  a nova classe recebe como base uma antiga e herda seus atributos:

Analise o seguinte código, uma modificação do anterior:



//Para criarmos classes e depois objetos em Prisma precisamos incluir a biblioteca 'classe':
inclua'classe';

//criando uma nova classe chamada conta_bancaria:
conta = Classe{
nome = '' , //dado nome do usuario da conta
saldo = 0, //definindo um saldo padrão = zero

despositar = funcao( este , n ) 
     este.saldo = este.saldo + n; //somando o novo deposito ao saldo atual;
fim ;
sacar = funcao( este , n  )
   este.saldo = este.saldo - n ; //subtraindo do saldo atual
fim ;
poupanca = 0 ;  //definindo valor da poupanca

transf_para_poupanca = funcao(este , n )
       imprima('\n' , sis.data() , '\nDeposito da conta corrente para poupanca, valor: ' , n , '\n' );
     este.saldo = este.saldo - n; //tirando da conta corrente
    este.poupanca = este.poupanca + n; //colocando na poupanca
fim ;

transf_para_conta = funcao ( este , n )
   imprima('\n' , sis.data() , '\nDeposito da poupanca para conta, valor: ' , n , '\n' );
    este.poupanca = este.poupanca - n;
    este.saldo = este.saldo + n;
fim  ; //nunca se esqueça de separar por ponto e vírgula ou vírgula

mostre_nome = funcao(este) imprima('\nNome :' , este.nome, '\n') fim;
mostre_saldo = funcao( este )  imprima( 'Saldo conta corrente :' , este.saldo, '\n' ) fim ;
mostre_poupanca = funcao( este ) imprima('Poupanca :' , este.poupanca, '\n' ) fim

}


//feito a classe conta podemos fazer objetos a partir dela como o metodo novo

conta_padaria = conta:novo({nome = 'Conta padaria'});
//se preferir pode descartar os parênteses quando passar uma tabela.
conta_padaria:mostre_nome();
conta_padaria:mostre_saldo();
conta_padaria:mostre_poupanca();

//voce pode passar uma tabela redefinindo os dados:
conta_pessoal = conta:novo{nome = 'Paulo-conta' , saldo = 250.00 };
conta_pessoal:mostre_nome(); //imprime o nome
conta_pessoal:mostre_saldo(); //imprime o saldo conta corrente
conta_pessoal:mostre_poupanca(); //imprime saldo poupanca
conta_pessoal:despositar( 1000.00 ); //deposita
conta_pessoal:mostre_saldo(); //imprime saldo
conta_pessoal:transf_para_poupanca( 250.00 ); //transfere para poupanca
conta_pessoal:mostre_saldo();  //imprime saldo
conta_pessoal:mostre_poupanca(); //imprime poupanca


//podemos criar uma outra classe a partir da classe conta, heranca
conta2 = Classe( conta ); //ao passar a classe conta como parametro
// a nova classe conta2 tera automaticamente os dados e metodos
//da classe conta; isso se chama heranca

//adicionando dados e metodos extras que nao existem em conta
//veja que a adicao foi posterior, sem usar chaves, isso não importa:
conta2.numero = 0;
conta2.emprestimo_total = 0;
conta2.emprestimo_restante_pagar = 0;
conta2.emprestimo_parcela = 0;
conta2.emprestimo_num_parcelas = 0;

conta2.mostre_extrato = funcao(este)
   imprima'-------------------------------------------------------------';
   imprima'                    extrato geral                              ';
   imprima( 'Titular da conta:' , este.nome , '\n');
   imprima('saldo conta:', este.saldo );
   imprima( 'saldo poupanca:' , este.poupanca );
   imprima( '\nEmprestimo:' );
   imprima( 'Valor total a pagar:' , este.emprestimo_total );
   imprima("Total restante a pagar:" , este.emprestimo_restante_pagar);
   imprima('Valor de cada parcela:' , este.emprestimo_parcela );
   imprima( 'Parcelas restantes:' , este.emprestimo_num_parcelas );
fim

conta2.emprestar = funcao( este , valor , parcelas )

      este.emprestimo_total = valor + valor * 0.2; //20 por cento do total
      este.emprestimo_restante_pagar = este.emprestimo_total;
      este.emprestimo_parcela = este.emprestimo_total / parcelas;
      este.emprestimo_num_parcelas = parcelas;

fim

conta2.pagar_emprestimo = funcao ( este )
       este:sacar( este.emprestimo_parcela );//esta funcao foi herdada de conta.
       este.emprestimo_restante_pagar  =  //nao tem problema ir para outra linha
       este.emprestimo_restante_pagar - este.emprestimo_parcela;
       
       este.emprestimo_num_parcelas = este.emprestimo_num_parcelas - 1;
       //diminuiu uma parcela;       
fim

//criando um novo objeto com alguns dados:
cliente10 = conta2:novo( {nome = 'Maria' , numero = 10 , saldo = 12000 } )
poe('------------------------------------------------------');
cliente10:mostre_nome();
cliente10:mostre_saldo();
cliente10:emprestar ( 1000.00 , 12 );
cliente10:mostre_extrato();
poe'\n------------------------------------------------------------------';
poe'             paga 1 parcela            ';

cliente10:transf_para_poupanca( 2000.00);
cliente10:pagar_emprestimo();
cliente10:mostre_extrato();
cliente10:pagar_emprestimo();
cliente10:pagar_emprestimo();
cliente10:pagar_emprestimo();
cliente10:pagar_emprestimo();

cliente10:mostre_extrato();




Veja a saída, em Ubuntu 14.04:

(http://www.linguagemprisma.net/images/ooPrisma.png)



                                                                                       HERANÇA MÚLTIPLA

Herdar dados e métodos de várias classes ao mesmo tempo. Não há muita diferença do exemplo anterior, basta na hora de criar a nova classe passar quantas classes antigas precisar como parâmetro, veja:

nova_classe = Classe(  {meus_novos_atributos...} , classe_antigaA , classeAntigaB , ... );
Note que para mais de um parâmetro não podemos omitir os parênteses da função Classe;






Bom, pessoal, é isso aí, orientação a objetos não é muito fácil, mas merece dedicação, pois quando se programa assim fica bem organizado.
O exemplo acima é sem interface gráfica, mas basta adaptar e usar a criatividade com ig que o trabalho será legal.

Ok, qualquer dúvida deixe um comentário.

Visite o site:    http://linguagemprisma.net (http://linguagemprisma.net)
Título: Re:orientação a objetos, simples exemplo
Enviado por: rafael online Junho 27, 2017, 12:08:44 AM
Oi Adalberto,

Estou tentando trabalhar com classes, é bem interessante se parece muito com uma linguagem de consulta estruturada.

meu problema está em como pegar os índices da classe:

a intenção aqui seria pegar as cadeias e os valores

cliente=Classe{blablabla}

funcao cliente:mostretudo()
para indice, valores em ipares(este) inicio
imprima (indice,valores) fim
fim
Título: Re:orientação a objetos, simples exemplo
Enviado por: adalberto online Junho 27, 2017, 10:32:54 AM
Ao usar os dois pontos, dentro da funcao estará disponivel um ponteiro para a tabela clientes na variavel reservada este. Basta vc usar a palavra este como se fosse a propria tabela.

Ex.

cliente =Classe { nome = ''; telef = ''};
//metodos
funcao cliente:def_nome(nome)
  este.nome = nome;
fim
funcao cliente:def_telefone (tel)
  este.telef = tel;
fim

funcao cliente:mostretudo()
  poe'------------------'
imprima(este.nome, este.telef);
fim


É muito bom programar neste estilo, depois de vc ter uma colecao de classes prontas programar fica bem mais fácil.

Falou.

Título: Re:orientação a objetos, simples exemplo
Enviado por: rafael online Junho 27, 2017, 09:04:47 PM
Acho que não fui muito claro:

Quero pegar tudo que estiver dentro da classe,

Até coloquei uma tabela dentro da classe e consegui pegar os índices e valores da tabela mas da classe não vai:


inclua'classe'   //nome da lib é com letra minuscula

//classe cliente:
cliente = Classe{ nome='Sem Nome';  tel='61 00000 0000'; }

//funcao construtora
funcao cliente:construtor(nome,tel)
este.nome=nome;
este.tel=tel;
fim

//outros métodos:
funcao cliente:mostre()
imprima('Cliente:',este.nome, 'Tel:', este.tel);
fim

funcao cliente:denome(nome)
este.nome=nome;
fim
funcao cliente:defone(tel)
este.tel=tel;
fim

rafael=cliente:novo{}
rafael:construtor('Rafael','61 00000 9290')

funcao cliente:mostretudo()
se tipo(este.nome)=='tabela' entao
para i, v em ipares(este.nome)  inicio
imprima(i,v) fim
senao
imprima (este.nome) fim
fim


cliente.nome={}
cliente.nome[1]='RAFAEL'
cliente.nome[2]='ALVES'
cliente.nome[3]='LEMOS'

cliente:mostretudo()


imprima(tipo(cliente.nome))
imprima(tipo(cliente.tel))
imprima(tipo(cliente))


eu fiz o mesmo para ipares na classe mas não retorna nem cadeias, nem índices e nem valores.
Título: Re:orientação a objetos, simples exemplo
Enviado por: adalberto online Junho 28, 2017, 12:46:20 PM
Vamos ver se eu entendi, vc quer pegar todos os membros da classe.

Os métodos ficam guardados em uma meta-tabela oculta com o nome de __index (duplo underline);

Os dados ficam normalmente nos campos, já que 'este' representa a própria tabela  então basta passar a variável 'este' para o 'pares'.

Veja o código abaixo:


inclua'classe'   //nome da lib é com letra minuscula

//classe cliente:
cliente = Classe{nome='Sem Nome',tel = 'Sem numero'}

//funcao construtora

funcao cliente:construtor(nome,tel)
este.nome=nome;
este.tel=tel;
fim


//outros métodos:
funcao cliente:mostre()
imprima('Cliente:',este.nome, 'Tel:', este.tel);
fim

funcao cliente:denome(nome)
este.nome=nome;
fim
funcao cliente:defone(tel)
este.tel=tel;
fim

rafael=cliente("Rafael",'444444444444');

funcao cliente:mostreMetodos()
para i, v em pares(este.__index)  inicio
  imprima(i .. ':' ,v)
fim
fim

funcao cliente:mostreDados()
  para i, v em pares(este)  inicio
    imprima(i .. ':' ,v)
  fim
fim

funcao cliente:mostretudo()
  poe'--------------------------------';
  este:mostreMetodos();
  poe'================================';
  este:mostreDados();
  poe'--------------------------------';
fim


rafael:mostretudo();


Falou, até mais.



Título: Re:orientação a objetos, simples exemplo
Enviado por: rafael online Junho 28, 2017, 09:12:01 PM
Oi Adalberto não é isso veja:

inclua'classe'   //nome da lib é com letra minuscula
clienteC = Classe{nome='Sem Nome',tel = 'Sem numero'}
clienteT={'rafael','lemos'}

imprima(desempacote(clienteT)) // saída > rafael    lemos
imprima(desempacote(clienteC)) // saída > nome='Sem Nome'     tel='Sem numero'

Quero pegar o nome e tel e não 'Sem Nome' e 'Sem numero'
Título: Re:orientação a objetos, simples exemplo
Enviado por: rafael online Junho 29, 2017, 01:22:51 PM
Boa tarde Adalberto,

Consegui fazer com json ficou do jeito que eu queria:
teste.json:

{
"Usuarios":
[{
"Nome": "Rafael Alves Lemos",
"Senha": "2d8d596a0b97569f9226a8c33ed9c6dbc8d88120",
"Usuario": "rafael",
"Grupo": "ADM"

}],

"Equipamentos":
[{
"Tipo": "Painel",
"Nome": "TMCAL5MN",
"Modelo": "Mikrotik RB921 - NetMetal",
"IP": "127.0.0.1",
"Ativo": "SIM"
}]
}



json.prisma:

local json = inclua'json'

tab, err = json.decod_arquivo('teste.json');

se nao tab entao erro(err) fim;

para i, v em pares(tab) inicio
imprima(i)
para r,f em pares (tab[i]) inicio
imprima (r)
para l, t em pares (f) inicio
imprima (l,t)
fim
fim
fim
Título: Re:orientação a objetos, simples exemplo
Enviado por: rafael online Junho 29, 2017, 02:23:38 PM
Minha intenção é criar um Banco de Dados,

Mas já tô vendo que se o arquivo for maior que 10MB já dá um atraso.

Pra guardar poucos dados talvez seja bom porque não precisa instalar um banco de dados convencional.

Título: Re:orientação a objetos, simples exemplo
Enviado por: adalberto online Junho 29, 2017, 06:05:12 PM
Blz, mas vc já deu uma olhada na biblioteca reg.pris? Você pode salvar tabelas com ela, creio que seja mais rápida que a json.

Para pegar as chaves no comando 'para' basta usar a primeira variável junto com o pares();

para chave, valor em pares(tab) inicio
   imprima(chave);
fim