Usar funções em vez de procedures. Como fazer isso?
Moderador: Moderadores
-
labaroazul
- Usuário Nível 2

- Mensagens: 83
- Registrado em: 26 Fev 2008 14:52
- Localização: São Paulo - SP
- Contato:
Usar funções em vez de procedures. Como fazer isso?
Bom dia, amigos! :* -:]
Para evitar o erro "Too many symbols" ao compilar o programa, foi sugerido a quem perguntou, em um outro tópico aqui do fórum, que fossem usadas funções no lugar de procedures.
Assim, em vez de:
DO CADASTRO //CHAMANDO O PROCEDURE DE CADASTRO
usar:
CADASTRO() //CHAMANDO A FUNÇÃO CADASTRO
E, em vez de
PROCEDURE CADASTRO
BLA, BLA, BLA
RETURN(.T.)
usar:
FUNCTION CADASTRO
BLA, BLA, BLA
RETURN NIL
Até aí, beleza.... :)Pos
Agora, como fazer para usar isso em um prg que chama outros prgs? :(Neg
Vou explicar melhor: Tenho um prg que eu chamo de Menu.prg, que chama outros prgs:
MENU TO OP
DO CASE
CASE OP = 0
EXIT
CASE OP = 1
DO CADCLI //CHAMA O PRG CONTENDO A TELA PARA CADASTRO DE CLIENTES.
CASE OP = 2
DO CADPRO //CHAMA O PRG DO CADASTRO DE PRODUTOS
ENDCASE
Já possuo, no mesmo Menu.prg, o comando
SET PROCEDURE TO FUNCOES
que chama o Funcoes.prg onde eu armazeno funções gerais do sistema, como as de controle de acesso em rede. Posso usar esse comando assim:
SET PROCEDURE TO FUNCOES
SET PROCEDURE TO CADCLI
SET PROCEDURE TO CADPRO
....? ´o)
Porque nesses prgs (Cadcli.prg e CadPro.prg) por exemplo, eu já coloquei assim:
FUNCTION CADCLI()
//AQUI TODO O PROCEDIMENTO DE CADASTRO, CONSULTA, ALTERACAO E EXCLUSAO DE CLIENTES E EXIBICAO EM UMA DBEDIT()
RETURN NIL
:f
Alguém pode me ajudar? :xau
Para evitar o erro "Too many symbols" ao compilar o programa, foi sugerido a quem perguntou, em um outro tópico aqui do fórum, que fossem usadas funções no lugar de procedures.
Assim, em vez de:
DO CADASTRO //CHAMANDO O PROCEDURE DE CADASTRO
usar:
CADASTRO() //CHAMANDO A FUNÇÃO CADASTRO
E, em vez de
PROCEDURE CADASTRO
BLA, BLA, BLA
RETURN(.T.)
usar:
FUNCTION CADASTRO
BLA, BLA, BLA
RETURN NIL
Até aí, beleza.... :)Pos
Agora, como fazer para usar isso em um prg que chama outros prgs? :(Neg
Vou explicar melhor: Tenho um prg que eu chamo de Menu.prg, que chama outros prgs:
MENU TO OP
DO CASE
CASE OP = 0
EXIT
CASE OP = 1
DO CADCLI //CHAMA O PRG CONTENDO A TELA PARA CADASTRO DE CLIENTES.
CASE OP = 2
DO CADPRO //CHAMA O PRG DO CADASTRO DE PRODUTOS
ENDCASE
Já possuo, no mesmo Menu.prg, o comando
SET PROCEDURE TO FUNCOES
que chama o Funcoes.prg onde eu armazeno funções gerais do sistema, como as de controle de acesso em rede. Posso usar esse comando assim:
SET PROCEDURE TO FUNCOES
SET PROCEDURE TO CADCLI
SET PROCEDURE TO CADPRO
....? ´o)
Porque nesses prgs (Cadcli.prg e CadPro.prg) por exemplo, eu já coloquei assim:
FUNCTION CADCLI()
//AQUI TODO O PROCEDIMENTO DE CADASTRO, CONSULTA, ALTERACAO E EXCLUSAO DE CLIENTES E EXIBICAO EM UMA DBEDIT()
RETURN NIL
:f
Alguém pode me ajudar? :xau
Windows XP Professional + Clipper 5.2e + Exospace + Dbase III Plus + SIX3 + NoDosImp + LXPic
"O trabalho afasta três males: o vício, a pobreza e o tédio." (Voltaire)
Site: http://www.labaroazul.xpg.com.br
Repositório: http://www.4shared.com/dir/31334106/e79 ... aring.html
"O trabalho afasta três males: o vício, a pobreza e o tédio." (Voltaire)
Site: http://www.labaroazul.xpg.com.br
Repositório: http://www.4shared.com/dir/31334106/e79 ... aring.html
Na verdade, vc coloca no seu arquivo rmk e lnk a informação de quais são os arquivos para compilar.
Vc não precisa colocar o "set procedure to ..."
No set procedure ou no arquivo rmk e lnk vc coloca o nome do arquivo prg, mas dentro do sistema vc coloca a chamada da função ou procedimento.
Outra coisa, procedure não retorna valor. Função deve obrigatoriamente retornar.
Se continuar com dúvidas, avise.
Espero ter ajudado. Boa sorte.
Vc não precisa colocar o "set procedure to ..."
No set procedure ou no arquivo rmk e lnk vc coloca o nome do arquivo prg, mas dentro do sistema vc coloca a chamada da função ou procedimento.
Outra coisa, procedure não retorna valor. Função deve obrigatoriamente retornar.
Se continuar com dúvidas, avise.
Espero ter ajudado. Boa sorte.
"TRS-80/Sincler/Apple/PC - Clipper Winter 85, tlink 1.0 [pc 10 MHz - 640K] {NEZ 8000 2Kb RAM}"
{POG - Programação Orientada a Gambiarra}
{POG - Programação Orientada a Gambiarra}
Não. O retorno de função é opcional. A função retorna pura e simplesmente sem um RETURN ao final do código.Outra coisa, procedure não retorna valor. Função deve obrigatoriamente retornar.
[]'s
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.
---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.
---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
- Pablo César
- Usuário Nível 7

- Mensagens: 5312
- Registrado em: 31 Mai 2006 10:22
- Localização: Curitiba - Paraná
Re: Usar funções em vez de procedures. Como fazer isso?
Você ainda pode continuar chamando o seu módulo CADASTRO com o comando DO. Mas eu o utilizo quando este módulo for um PRG (aqui no seu exemplo: é o CADASTRO.PRG).labaroazul escreveu:que fossem usadas funções no lugar de procedures.
Código: Selecionar todos
Assim, em vez de: DO CADASTRO //CHAMANDO O PROCEDURE DE CADASTRO usar: CADASTRO() //CHAMANDO A FUNÇÃO CADASTRO
Código: Selecionar todos
E, em vez de
PROCEDURE CADASTRO
BLA, BLA, BLA
RETURN(.T.)
usar:
FUNCTION CADASTRO
BLA, BLA, BLA
RETURN NILCódigo: Selecionar todos
// Aplicativo TESTE.PRG
SET DATE TO BRITISH
SET CENTURY ON
dDIA:=CTOD("25/12/0000")
QUEDIA:=VEJADIA(dDIA)
? QUEDIA
FUNCTION VEJADIA(dData)
Local VD:={"Domingo","Segunda-feira","Ter‡a-feira","Quarta-feira","Quinta-feira","Sexta-feira","S bado"}
ODIA:=DOW(dData)
VRET:=VD[ODIA]
RETURN VRET
// Fim do arquivo TESTE.PRG
Isto você não vai usar mais, esta configuração. Pois ela serve para manter a compatibilidade de versões anteriores do Clipper e é obsoleta e descontinuada.possuo, no mesmo Menu.prg, o comandoCódigo: Selecionar todos
SET PROCEDURE TO FUNCOES
Se você tem módulo como aquele que eu mencionei CADASTRO.PRG, servirá para você entender que naquele PRG você tem a rotina de CADASTRO e nada mais. Agora se você precisar fazer rotinas comuns aos outros módulos como por exemplo aquele que eu exemplifiquei, então você poderia "armazená-las" no FUNCOES.PRG com as suas devidas decalrações de nome de cada função. Se a sua dificuldade está incluir este PRG de funções, aí ja seria uma questão de definição na hora de compilação. Eu por exemplo que uso muito o RTLINK e até com BLINKER eu faço uma arquivo .BAT, assim:
Código: Selecionar todos
@ECHO OFF
CLIPPER ARQUIVO_PRINCIPAL /B > LOG.TXT
IF ERRORLEVEL 1 GOTO ERRO
CLIPPER FUNCOES /B > LOG.TXT
CLIPPER HELP /B
IF ERRORLEVEL 1 GOTO ERRO
CLIPPER ERRORSYS /M /N
IF ERRORLEVEL 1 GOTO ERRO
RTLINK FI ARQUIVO_PRINCIPAL,FUNCOES,HELP,ERRORSYS,__WAIT,TIMESLIC LIB CT
ARQUIVO_PRINCIPAL.EXE
GOTO FIN
:ERRO
TYPE LOG.TXT
PAUSE
GOTO FIN
:FINNa impede de você colocar estas funções no módulo CADASTRO.PRG.nesses prgs (Cadcli.prg e CadPro.prg) por exemplo, eu já coloquei assim:
Código: Selecionar todos
FUNCTION CADCLI() //AQUI TODO O PROCEDIMENTO DE CADASTRO, CONSULTA, ALTERACAO E EXCLUSAO DE CLIENTES E EXIBICAO EM UMA DBEDIT() RETURN NIL
"Too many symbols" também pode ser um excesso de uso de variaveis veja esta indicação: http://www.ousob.com/ng/clerr/ngd24b.php
Um clip-abraço !
Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
- Pablo César
- Usuário Nível 7

- Mensagens: 5312
- Registrado em: 31 Mai 2006 10:22
- Localização: Curitiba - Paraná
Sim mas o que talvez o colega quis dizer é que utilizando o retorno de funções não precisaria estar declarando variaveis novas e mais ainda do tipo PUBLICAS que consomem memória. Por isso eu também mencionei (sem ter visto seus posts) que dá para utilizar o retorno das funções. Se bem que utilizei um exemplo "não sintetizado", mas foi para dar exemplo e evidenciar o seu uso.Maligno escreveu:Não. O retorno de função é opcional. A função retorna pura e simplesmente sem um RETURN ao final do código.Outra coisa, procedure não retorna valor. Função deve obrigatoriamente retornar.
Um clip-abraço !
Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Você interpretou errado, a meu ver.
O que o colega GVC disse foi "Outra coisa, procedure não retorna valor. Função deve obrigatoriamente retornar.", e isso não é verídico. O fato é: o uso de função não pressupõe o retorno de valor algum. Sequer exige um RETURN.
O que o colega GVC disse foi "Outra coisa, procedure não retorna valor. Função deve obrigatoriamente retornar.", e isso não é verídico. O fato é: o uso de função não pressupõe o retorno de valor algum. Sequer exige um RETURN.
[]'s
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.
---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.
---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
[Maligno]
Sempre recebi avisos do compilador que devo retornar valor no retorno de uma função, mesmo que seja Nil.
O objetivo das funções é retoenar um valor. Eu uso-as muito e sempre retorno algo, mesmo o Nil que não será usado.
O Clipper entende que acabou uma procedure ou função quando encontra a declaração de uma nova procedure / função / fim de arquivo.
Vou verificar...
[Pablo César]
O "DO nome_do_procedimento" era para manter a compatibilidade com o DBase. Da versão summer´87 em diante, isso não era mais necessario. Adimito que não lembro se o clipper´86 aceitava essa necessidade.
Assim como o "SET PROCEDURE TO nome_do_arquivo" foi mantido para manter compatibilidade com as primeiras versões do clipper. Vc informa no arquivo principal quais são os PRG´s que devem ser agregados ao sistema. Vc tb pode fazer isso em outros módulos, mas não é uma boa prática.
Como os Clippeiros "evoluiram" para outros métodos, isso não é muito usados atualmente. (Não quer dizer que não seja.)
Como os "linkers" evoluiram, o método de compilação tb mudou. Compilamos módulos individuais e não o sistema todo.
Lembrando que isso é uma prática. Nada impede de que o Clippeiro continue usando o "set procedure to ...". (cada louco com a sua mania. eh! eh! eh!)
Curioso...... "Outra coisa, procedure não retorna valor. Função deve obrigatoriamente retornar.", e isso não é verídico. O fato é: o uso de função não pressupõe o retorno de valor algum. Sequer exige um RETURN.
Sempre recebi avisos do compilador que devo retornar valor no retorno de uma função, mesmo que seja Nil.
O objetivo das funções é retoenar um valor. Eu uso-as muito e sempre retorno algo, mesmo o Nil que não será usado.
O Clipper entende que acabou uma procedure ou função quando encontra a declaração de uma nova procedure / função / fim de arquivo.
Vou verificar...
[Pablo César]
O "DO nome_do_procedimento" era para manter a compatibilidade com o DBase. Da versão summer´87 em diante, isso não era mais necessario. Adimito que não lembro se o clipper´86 aceitava essa necessidade.
Assim como o "SET PROCEDURE TO nome_do_arquivo" foi mantido para manter compatibilidade com as primeiras versões do clipper. Vc informa no arquivo principal quais são os PRG´s que devem ser agregados ao sistema. Vc tb pode fazer isso em outros módulos, mas não é uma boa prática.
Como os Clippeiros "evoluiram" para outros métodos, isso não é muito usados atualmente. (Não quer dizer que não seja.)
Como os "linkers" evoluiram, o método de compilação tb mudou. Compilamos módulos individuais e não o sistema todo.
Lembrando que isso é uma prática. Nada impede de que o Clippeiro continue usando o "set procedure to ...". (cada louco com a sua mania. eh! eh! eh!)
"TRS-80/Sincler/Apple/PC - Clipper Winter 85, tlink 1.0 [pc 10 MHz - 640K] {NEZ 8000 2Kb RAM}"
{POG - Programação Orientada a Gambiarra}
{POG - Programação Orientada a Gambiarra}
Se você usar o switch /W para compilar, o compilador realmente reclamará a falta de um RETURN. Mas é apenas por quê ele "pensa" que algo está errado.gvc escreveu:Sempre recebi avisos do compilador que devo retornar valor no retorno de uma função, mesmo que seja Nil.
Não exatamente. O real objetivo da função é modularizar o código. O retorno desta é uma opção a mais de uso para, entre outras coisas, aproveitar sua saída como entrada de outra função.O objetivo das funções é retoenar um valor. Eu uso-as muito e sempre retorno algo, mesmo o Nil que não será usado.
É isso mesmo. O que torna desnecessário o uso do RETURN. Mas lembrando que o /W, se utilizado, vai fazer o compilador "apitar". Eu nunca usei esse switch.O Clipper entende que acabou uma procedure ou função quando encontra a declaração de uma nova procedure / função / fim de arquivo.
[]'s
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.
---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.
---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
- vagucs
- Membro Master

- Mensagens: 1480
- Registrado em: 10 Jul 2004 10:45
- Localização: Ipanema - MG
- Contato:
Desse assunto entendo.
Bom, em Delphi, como o maligno mesmo sabe, a logica é este, FUNCTION sempre retorna um valor, e PROCEDURE não.
A um tempo atrás, o clipper summer, tinah esta diferenciação, tanto que se você criasse um sistema com PROCEDURES retornando algo, com um grande numero de procedures, poderia verificar alguns caracteres estranhos na tela, coisa que nunca impediu nenhum sistema de rodar, se fizer o contrario tambem, criar muitas FUNCITIONS sem colocar um return nelas, nem que seja RETURN "" (Nil).
No Clipper 5.x para frente, existem os 2 comandos (Óbvio), acho que mais para compatibilidade do que para qualquer outra função. Quando criei o DClip eu estudei a estrutura toda do arquivo e até mesmo qual a diferença fisica no EXE entre o comando PROCEDURE e FUNCTION, e verifiquei que, se você usa o clipper 5.x, independente de usar FUNCTION ou PROCEDURE, fisicamente no programa EXE final não tem diferença nenhuma, o código compilado é sempre o mesmo. Mas acho interessante, para questão de didatica do fonte, você padronizar, FUNCTION é porque tem retorno e PROCEDURE é porque não tem.
Bom, em Delphi, como o maligno mesmo sabe, a logica é este, FUNCTION sempre retorna um valor, e PROCEDURE não.
A um tempo atrás, o clipper summer, tinah esta diferenciação, tanto que se você criasse um sistema com PROCEDURES retornando algo, com um grande numero de procedures, poderia verificar alguns caracteres estranhos na tela, coisa que nunca impediu nenhum sistema de rodar, se fizer o contrario tambem, criar muitas FUNCITIONS sem colocar um return nelas, nem que seja RETURN "" (Nil).
No Clipper 5.x para frente, existem os 2 comandos (Óbvio), acho que mais para compatibilidade do que para qualquer outra função. Quando criei o DClip eu estudei a estrutura toda do arquivo e até mesmo qual a diferença fisica no EXE entre o comando PROCEDURE e FUNCTION, e verifiquei que, se você usa o clipper 5.x, independente de usar FUNCTION ou PROCEDURE, fisicamente no programa EXE final não tem diferença nenhuma, o código compilado é sempre o mesmo. Mas acho interessante, para questão de didatica do fonte, você padronizar, FUNCTION é porque tem retorno e PROCEDURE é porque não tem.
- Pablo César
- Usuário Nível 7

- Mensagens: 5312
- Registrado em: 31 Mai 2006 10:22
- Localização: Curitiba - Paraná
Sim é a mesma coisa, colega.
Um clip-abraço !
Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Os parênteses tem apenas três funções: forçar o compilador a avaliar uma expressão numa ordem de precedência diferente do padrão E/OU melhorar a legibilidade do código E/OU expressar frescura. 
[]'s
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.
---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.
---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
- vagucs
- Membro Master

- Mensagens: 1480
- Registrado em: 10 Jul 2004 10:45
- Localização: Ipanema - MG
- Contato:
No clipper o parâmetro sempre indica que a expressão deve ser acumulada no Stack antes do proximo comando. Assim na versão 5.x podemos executar uma wave numa string
&("VAR")
Por exemplo, pois o parentese faz com que VAR seja acumulado no astack e o wave(macro) seja executado nele.
No summer isto nao era suportado.
&("VAR")
Por exemplo, pois o parentese faz com que VAR seja acumulado no astack e o wave(macro) seja executado nele.
No summer isto nao era suportado.
- Pablo César
- Usuário Nível 7

- Mensagens: 5312
- Registrado em: 31 Mai 2006 10:22
- Localização: Curitiba - Paraná
Adicionando ao seu comentário (um pouco sarcástico do Netavin). O parêntese é um indicador de agrupamento e também identifica uma chamada de função.
O NG em português fala sobre "Argumentos de comando":
O que seria desnecessário para esta ocasião, não é Wagner ?vagucs escreveu:o parentese faz com que VAR seja acumulado no astack e o wave(macro) seja executado nele
O NG em português fala sobre "Argumentos de comando":
Mas em sintese não afeta na situação indaga pelo colega ABeltrani.Nas versoes anteriores do Clipper, bem como em outros dialetos, as variaveis macro geralmente eram utilizadas para especificar os argumentos de comandos que exigiam valores de texto literal. Isto incluia todos os argumentos de comando de arquivos, bem como comandos SET com argumentos de comuta. Nestes casos, agora você pode utilizar uma expressao estendida no lugar do argumento literal caso a expressao esteja entre parênteses. Por exemplo:
xcDatabase = "Invoices"
USE &xcDatabase.
pode ser substituido por:
xcDatabase = "Invoices"
USE (xcDatabase)
É importante utilizar expressoes estendidas, em especial se você estiver usando variaveis locais e estaticas.
Quando as variaveis macro sao transformadas em cadeias de caracteres, os nomes das variaveis macro ficam ocultos na string e nao sao compilados.
Um clip-abraço !
Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.

