Página 1 de 1

Dúvida em código OOP

Enviado: 06 Fev 2016 12:52
por Vlademiro
Pessoal,

Ontem eu perdi meio dia com um problema e resolvi reproduzi-lo abaixo para que alguém não perca o mesmo tempo que eu perdi.

Código: Selecionar todos

#include "hbclass.ch"

FUNCTION MAIN()
LOCAL c := myClass():New()

   ? c:Test()

RETURN NIL
***
CLASS myClass 

   DATA test INIT NIL
   
   METHOD test()
   METHOD NEW() CONSTRUCTOR

END CLASS

METHOD NEW()

   ::test := 10
   ::test()   

RETURN Self

METHOD Test()

   ? "Inside test"
   ? ::test

RETURN Self

Em suma, se eu criar uma variável com o mesmo nome de um método o programa não vai distinguir corretamente uma coisa da outra.
Na linha onde tem o comando

Código: Selecionar todos

? ::teste 
o programa chamou o método test e não a variável test.
Ele deveria chamar o método se fosse assim :

Código: Selecionar todos

 ? ::test() 
Como o meu código estava no meio de outros do sistema acabei não conseguindo resolver o problema rapidamente e perdi bastante tempo.

Uso o :

Harbour 3.2.0dev (r1507030922)
Copyright (c) 1999-2015, http://harbour-project.org/

Dúvida em código OOP

Enviado: 09 Fev 2016 04:49
por alxsts
Olá!

Testei seu código e realmente o problema ocorre. Não sei se é um erro. Fiz algumas alterações e postei a dúvida para o Viktor. Vamos aguardar a resposta.
Dear Viktor.

Code shown below starts an infinite loop and runs until an error is caught by Windows (probablly stack overflow). This problem was reported by a member of the PC Toledo, brazilian xBase forum and I'm sending you the following questions:
1 - All we know that declaring a class method and an instance variable with the same name is not a good practice but why is this problem occurring?
2 - Is it an error where Harbour isn't able to distinguish between the method and the instance var?
3 - Is it a limitation inerithed from C language? (I know C has the same issue and Java does not)

Thank you in advance.

Please read code below:

Código: Selecionar todos

#include "hbclass.ch"

FUNCTION MAIN()

LOCAL c

   CLS

   AltD()

   c := myClass():New()
   
   ? c:Test()

RETURN NIL

***

CREATE CLASS myClass 

   PROTECTED:
   
   VAR test as numeric INIT 0
   
   EXPORTED:
      
   METHOD Test()
   METHOD New() // CONSTRUCTOR

END CLASS

METHOD New() class myClass

   ::Test := 10     
   ? ::Test      // expected to display instance var contents but invokes method Test 
   ::test()       // expected to invoke method Test --> point never reached

RETURN Self

METHOD Test()  class myClass

   ? "Inside test"  
   ? ::test   // expected to display instance var contents but Test method is invoked in infinite loop

RETURN Self

//---------------------------------------
Problem occurs in

Harbour 3.2.0dev (r1507030922)
Copyright (c) 1999-2015

and

Harbour 3.4.0dev (25f2ab9) (2015-08-27 21:43)
Copyright (c) 1999-2015, https://github.com/vszakats/harbour-core/

//-----------------------------------------------

There is another problem while debugging and inspecting the self variable (application starts the loop) but this should be treated by another thread.

Dúvida em código OOP

Enviado: 09 Fev 2016 16:12
por alxsts
Olá!

O Viktor respondeu:
vszakats commented 7 hours ago
Hi, it is case number 3. You probably saw it, but for reference Przemek also answered this in detail, here: https://groups.google.com/d/msg/harbour ... EQNu57AQAJ
Verificando a URL citada, é possível ver que se trata de uma resposta do Przemek sobre a mesma questão, postada no Google Groops. Creio que o autor do post (VLAD) seja você mesmo...

Conclusão: não use o mesmo nome para um método e uma variável de instância na mesma classe.

No teu código original faltam também os indicadores de escopo dos métodos e variáveis (protected:, hidden:, exported) e na declaração dos métodos é sempre bom especificar o nome da classe a que pertencem. Segundo o manual do xHarbour, é melhor usar a declaração VAR em lugar de DATA, como está no teu código. Creio que isto valha para Harbour também.

Dúvida em código OOP

Enviado: 11 Fev 2016 13:06
por Vlademiro
alxsts, obrigado por analisar o código que eu postei. Realmente foi eu quem postou a dúvida no fórum de desenvolvedores. Ele (Przemek ) disse que essa é uma característica herdada do Clipper. Ele disse que irá para a lista de correções mas com baixa prioridade.

A conclusão é a mesma que vc chegou : não coloque o mesmo nome para um método e uma variável.

Valeu!

Dúvida em código OOP

Enviado: 11 Fev 2016 13:19
por alxsts
Olá!

Já no Harbour 3.4, o Viktor classificou a ocorrência como "non-bug" e a fechou. Creio que nada será alterado com relação a isto.

Dúvida em código OOP

Enviado: 11 Fev 2016 13:41
por JoséQuintas
Sim.
Se isso for corrigido, por exemplo, eu e outros passaremos a ter muitos erros.

É que isso provavelmente também afetará o uso de objetos Windows. OLE.
E do jeito que está não precisamos nos preocupar se é método ou propriedade (função ou variável).

Talvez cause mais problemas consertar do que deixar assim.

Mas se alterarem, ok, vou ter que mexer em meus fontes, também não é nada extraordinário.
Vai ser problema pra LIBs abandonadas, sem suporte.

Dúvida em código OOP

Enviado: 11 Fev 2016 13:50
por alxsts
Olá!

Não entendi... você tem classes onde existem métodos e atributos com os mesmos nomes? E funciona?

Dúvida em código OOP

Enviado: 11 Fev 2016 14:09
por JoséQuintas
Não.
Objetos Excel, Exporer, ADO, etc, por exemplo.

Código: Selecionar todos

cnMySql := win_OleCreateObject( "ADODB.Connection" )

? cnMySql:State()

? cnMySql:State

Esse caso por exemplo, no momento nem sei se State é método ou propriedade.
Como não faz diferença HOJE, acabei deixando nos fontes tudo como método.
Se for corrigido, vou ter que corrigir meus fontes.... rs

imagine a quantidade de LIBs que podem ter feito o mesmo.
Neste caso deixou de ser Harbour, e passa a ser em qualquer componente Windows.
Mas de repente até pode aparecer um componente que usa isso de propriedade e método com mesmo nome.
De qualquer forma, alterar isso agora, deve afetar muita coisa já pronta.