Page 1 of 1

Preprocesado y clases

PostPosted: Mon Oct 24, 2005 4:25 pm
by jlcapel
Antonio,

Al utilizar los comandos de controles en clases creadas por mi, en algunos controles, me encuento con problemas del preprocesado.

Te pongo un ejemplo claro:

Code: Select all  Expand view
CLASS MiClase
           DATA  cDatoaCambiar AS CHARACTER INIT "Valor"
           METHOD NEW()  INLINE Self
           METHOD Prueba()
ENDCLASS

METHOD PRUEBA() CLASS MiClase
             LOCAL oDlg, oCbx
             LOCAL cCbx := "Uno"
             LOCAL aCbx := {"Uno","Dos")

             
             DEFINE DIALOG oDlg NAME "MiDialogo" OF oWnd

             REDEFINE COMBOBOX oCbx VAR cCbx ITEMS aCbx ;
                            ID 205 OF oDlg ;
                            ON CHANGE (::cDatoaCambiar := "Pepe .T.) ;
                            UPDATE

             ACTIVATE DIALOG oDlg
RETURN NIl


Si ejecutamos ese trozo de código, Fivewin arroja un error indicando algo parecido a esto:

Message not found oCombobox:cDatoaCambiar.

Esto ocurre por que en el procesado de este control es como sigue:
Code: Select all  Expand view
#xcommand REDEFINE COMBOBOX [ <oCbx> VAR ] <cVar> ;
             [ <items: PROMPTS, ITEMS> <aItems> ] ;
             [ ID <nId> ] ;
             [ <dlg:OF,WINDOW,DIALOG> <oWnd> ] ;
             [ <help:HELPID, HELP ID> <nHelpId> ] ;
             [ ON CHANGE <uChange> ] ;
             [ VALID   <uValid> ] ;
             [ <color: COLOR,COLORS> <nClrText> [,<nClrBack>] ] ;
             [ <update: UPDATE> ] ;
             [ MESSAGE <cMsg> ] ;
             [ WHEN <uWhen> ] ;
             [ BITMAPS <acBitmaps> ] ;
             [ ON DRAWITEM <uBmpSelect> ] ;
             [ STYLE <nStyle> ] ;
             [ PICTURE <cPicture> ];
             [ ON EDIT CHANGE <uEChange> ] ;
       => ;
          [ <oCbx> := ] TComboBox():ReDefine( <nId>, bSETGET(<cVar>),;
             <aItems>, <oWnd>, <nHelpId>, <{uValid}>, [{|Self|<uChange>}],;
             <nClrText>, <nClrBack>, <cMsg>, <.update.>, <{uWhen}>,;
             <acBitmaps>, [{|nItem|<uBmpSelect>}], <nStyle>, <cPicture>,;
             [<{uEChange}>] )


Y quedaría resuelto cambiado el Self por This. Algo así:

=> ;
[ <oCbx> := ] TComboBox():ReDefine( <nId>, bSETGET(<cVar>),;
<aItems>, <oWnd>, <nHelpId>, <{uValid}>, [{|this|<uChange>}],;
<nClrText>, <nClrBack>, <cMsg>, <.update.>, <{uWhen}>,;
<acBitmaps>, [{|nItem|<uBmpSelect>}], <nStyle>, <cPicture>,;
[<{uEChange}>] )




Este problema ocurre en varios controles.

Saludos,
José Luis Capel

PostPosted: Mon Oct 24, 2005 5:16 pm
by Antonio Linares
Jose Luis,

Una solución fácil es declarar:

local this := Self

y en vez de hacer ::cDatoaCambiar, hacer this:cDatoaCambiar

asi no hay que modificar los includes.

PostPosted: Mon Oct 24, 2005 6:02 pm
by jlcapel
Antonio,

Gracias!! La solución me parece correcta. No obstante.... sería interesante plantearse esos cambios a nivel preprocesado. Creo que no rompe ningún código existente. ¿Qué opinas?

Saludos,
José Luis Capel

PostPosted: Mon Oct 24, 2005 7:58 pm
by Antonio Linares
Jose Luis,

Mi opinión es que si hay varios objetos en ámbito, es preferible especificar explícitamente a cual queremos acceder, en vez de hacerlo automático, con el peligro de acceder al que no es.

PostPosted: Mon Oct 24, 2005 8:09 pm
by jlcapel
Antonio,

Estoy totalmente de acuerdo contigo. Sin embargo, con el preprocesado actual, existe una ambigüedad que hace que en tiempo de ejecución arroje un error.

La forma más elegante de solucionar esto es, desde mi humilde punto de vista, cambiar el preprocesado tal y como he comentado más arriba.

Saludos,
José Luis Capel
www.capelblog.com

PostPosted: Mon Oct 24, 2005 8:18 pm
by Antonio Linares
jlcapel wrote:La forma más elegante de solucionar esto es, desde mi humilde punto de vista, cambiar el preprocesado tal y como he comentado más arriba


Tu solución me parece muy buena, pero antes de implementarla habría que pensar si puede romper código existente de usuarios.

PostPosted: Tue Oct 25, 2005 4:54 am
by Hernan Diego Ceccarelli
Hola,
Yo ya me acostumbre al oSelf

Code: Select all  Expand view
local oSelf := Self




Como dice Jose Luis, muchos controles toman el Self como correpsonde por supuesto del argumento del codeblock. En fin es solucionable. :)

Salu2