close Warning: Can't synchronize with repository "(default)" (/var/svn/tolp does not appear to be a Subversion repository.). Look in the Trac log for more information.

Opened 16 years ago

Closed 16 years ago

#723 closed enhancement (fixed)

Class constructors

Reported by: pgea@… Owned by: Víctor de Buen Remiro
Priority: high Milestone: OOP Implementation
Component: OOP Version: 2.0.1
Severity: normal Keywords:
Cc:

Description

Quizá sería conveniente poder incorporar a la definición de la clase los distintos constructores que definamos.
Véase el archivo .tol adjunto.

Attachments (1)

ticket_3.ClassConstructors.tol (746 bytes) - added by pgea@… 16 years ago.

Download all attachments as: .zip

Change History (8)

Changed 16 years ago by pgea@…

comment:1 Changed 16 years ago by Víctor de Buen Remiro

Priority: normalhigh
Status: newassigned

En principio es una petición razonable, aunque en realidad no tendría porque ser sólo para métodos de construcción de instancias sino para devolver cualquier otra cosa. Lo que se está pidiendo se podría solucionar de una forma genérica dotando a Class de métodos estáticos, es decir, aquellos que no se llaman para una instancia determinada, sino para la clase usada como un mero espacio de nombres, sin accieso a los miembros de instancia alguna.

La cosa podría quedar así.

Class CPrueba {
  Real _.valor;
  Real GetValor(Real unused) { Copy(_.valor) };
  Real SetValor(Real val) { Real _.valor := val };

  static CPrueba New(Real val) { 
    CPrueba newPrueba = [[ Real _.valor = val ]]
  };
  static CPrueba Random(Real unused) { 
    CPrueba newPrueba = [[ Real _.valor = Rand(0,1) ]]
  }

};

CPrueba a = CPrueba::New(0.2);
CPrueba b = CPrueba::Random(?);

Habría algún problema con el parser y es que los nombres de las clases funcionan sintácticamente como operadores monarios, por lo que no pueden preceder a un operador binario como ::, y habría que retorcer una vez más el parser. Pero vamos es algo que ya se ha hecho para permitir la declaración de herencia Class <clase_heredada> : <clase_base> , y no creo que fuera más dificultoso.

También podría dar guerra el tema de que usas el nombre de la clase antes de acabar de crearla. Pero tampoco creo que eso sea muy dificil de resolver, bastará con retardar la creación de los métodos.

Si nadie tiene otra idea mejor podemos fijar esta capacidad como un objetivo en OOP con una prioridad media-alta, para que esté hecho antes de que empiece a proliferar el código con mal aspecto.

comment:2 Changed 16 years ago by Víctor de Buen Remiro

Milestone: OOP Implementation
Status: assignedaccepted
Version: 2.0.1

comment:3 Changed 16 years ago by pgea@…

A mi no me parece mala idea.
Supongo que al estilo de cómo se soluciona/solucione #722 los constructores se incluirán como métodos de la clase que pueden ser llamados directamente desde la clase, sin instancia alguna.

Sobre la cuestión del parser, no sé si lo siguiente tiene también algo que ver, pero se encuentran dificultades para usar el nombre de una clase antes de que sea definida.
¿Podrían declararse las clases y luego definirse?

Por ejemplo, así se podrían tener dos clases A y B, la primera con un método que recibe como argumento un objeto tipo B y la segunda uno con un argumento tipo A.
Hasta ahora la primera en definirse recibe un argumento tipo NameBlock, pues no puede citarse el nombre del objeto hasta que haya sido definido.

comment:4 Changed 16 years ago by Víctor de Buen Remiro

Sí, lo mejor será poder declarar las clases antes de usarlas.

Por una parte habrá que hacer que el parser acepte la sintaxis que creo que será sencillo en principio. Sólo me cabe la duda de qué hacer cuando se declare varias veces una misma clase. Eso puede ocurrir si varias clases en ficheros distintos usan una misma clase predeclarada. Podría obligarse a predeclararla en un archivo previo y quizás hasta sea buena constumbre, pero tampoco parece muy complicado que se acepte sin más, pues basta con que la segunda y posteriores predeclaraciones no hagan nada en absoluto.

Internamente sólo hay una función para ver si existe una clase

BClass* FindClass(const BText& name)

Habría que añadirle un argumento que especifique si es preciso que esté definida o basta con que esté declarada

BClass* FindClass(const BText& name, bool defined)

y luego revisar todas las llamadas a la misma y dilucidar qué corresponde en cada caso.

comment:5 Changed 16 years ago by Víctor de Buen Remiro

La discusión sobre la predeclaración de clases se desvía al ticket #734

comment:6 Changed 16 years ago by Víctor de Buen Remiro

La discusión sobre los mimebros y métodos estáticos a las clases se desvía al ticket #735

comment:7 Changed 16 years ago by Víctor de Buen Remiro

Resolution: fixed
Status: acceptedclosed
Note: See TracTickets for help on using tickets.