https://foro.gambas-es.org/viewtopic.php?f=4&t=1204
-----------------------------------
shordi
Sabado, 11 Diciembre 2010, 22:01

Clonar Controles
-----------------------------------
Tengo que pasar un contenedor a una función para que procese su array Children. En gambas los objetos siempre se pasan por referencia. Dado lo que hago luego con los elementos del Children no me interesa modificar los originales y necesito trabajar sobre copias... pero no sé clonar objetos.

¿Alguien sabe cómo clonar controles? Cuando se pasan a una función o como parte de un Tag a otro control, siempre es por referencia. ¿No hay ninguna propiedad .clone o algo así por algún lado?


-----------------------------------
jguardon
Domingo, 12 Diciembre 2010, 12:28

Re: Clonar Controles
-----------------------------------
[quote]Objects are handled by reference only. If you need to copy an object of your 
own, you must do it yourself. Some native objects (like arrays) have a Copy() 
method, but most don't.

Regards,

-- 
Benoit Minisini
[/quote]

Es decir:

"Los objetos se manejan sólo por referencia. Si necesitas copiar un objeto, debes hacerlo tú mismo.
Algunos objetos nativos (como arrays) tienen un método Copy(), pero la mayoría no."


O sea, que lo veo difícil.

Pero se me ocurre por ejemplo que podrías copiar un contenedor con todos sus Children creando un nuevo objeto contenedor y copiando uno al otro... pero he leído que realmente lo que contendrá el nuevo contenedor serán referencias a los objetos contenidos en el primer contenedor. Lioso, no?

[url=http://http://en.wikipedia.org/wiki/Object_copy#Deep_vs._Shallow_vs._Lazy_copy]Diferencias entre Shallow copy y Deep copy.

Si alguien (como Fabián) nos puede arrojar más luz sobre esto, se lo agradeceremos.

Saludos


-----------------------------------
shordi
Domingo, 12 Diciembre 2010, 19:12

Re: Clonar Controles
-----------------------------------
Bueno... al final lo he resuelto con la primera función recursiva útil (es decir más allá de las prácticas teóricas) que recuerdo haber hecho... 
¡Qué bonita es la simplicidad!

Suerte


-----------------------------------
fabianfv
Domingo, 12 Diciembre 2010, 19:26

Re: Clonar Controles
-----------------------------------
Hola Shordi, Jesús. Creo que la cita de Benoit que hizo Jesús deja bastante en claro que aquí tenemos una limitación.

Lo único que puedo aclarar es que no hay que confundir el paso de argumentos con el manejo de objetos. Obviamente el manejo de objetos se hace a través de referencias (punteros) y el paso de argumentos se hace por valor a menos que se especifique byref tanto en la definición de los parámetros formales como en la aplicación de la función.

En este caso, el paso por valor a la función de Shordi no es de utilidad porque lo que se pasa es una referencia a un objeto, de modo que lo que se copia es el valor de la referencia, es decir un puntero, una dirección de memoria. En consecuencia, al manipular esa referencia dentro de la función se estaría manipulando el objeto original, no una copia.

Gambas no tiene una forma sencilla que yo conozca para clonar objetos. Esto no quiere decir que no exista, sólo que si existe yo no la conozco. Si es así, podría ser un feature request que deberíamos solicitarle a Benoit, si evaluamos que es algo realmente necesario (otros lenguajes tienen esa característica así que probablemente sea importante).

Pero para intentar aproximar una solución al problema de Shordi creo que deberíamos entender mejor que es lo que se intenta hacer, para buscar otro modo de hacerlo.

El camino que me parece obvio es escribir una rutina que tome la referencia que recibe esa función y a partir de ella cree un nuevo contenedor con todos los controles que éste contiene y establezca sus atributos con los mismos valores. Algo así:

[code linenumbers=false syntax=gambas]

'Reemplazar todas las apariciones de Container por el tipo de contenedor adecuado
PRIVATE FUNCTION procesaChildren(pContainer AS Container) AS Container

  DIM copia AS Container = copiar(pContainer)

  'Hacer algo con la copia

END


'Esta función podría ser miembro de una clase estática
'Reemplazar todas las apariciones de Container por el tipo de contenedor adecuado
'Verificar si se puede usar el tipo Object, probablemente Control sería más apropiado
PRIVATE FUNCTION copiar(pContainer AS Container) AS Container

  DIM nuevoContainer AS NEW Container() 'Especificar algún contenedor como parámetro del constructor
  DIM unObjecto, nuevoObjeto AS Object
  
  FOR EACH unObjeto IN pContainer.Children
    'Crear objetos del tipo correcto
    nuevoObjeto.Reparent(nuevoContainer)
    'Setear objetos
  NEXT  

END

[/code]

De todos modos la función copiar no es trivial y podría traer varios problemas nuevos que se deberían solucionar. Es cuestión de pensarlo un rato y probar algunas cosas (algunas de las sentencias que escribí podrían ser ilegales en Gambas, pero creo que se podría arreglar). En principio, gracias al polimorfismo sería válido crear controles mediante referencias de tipo Object y habría que verificar que al añadirlas al container éste convierta su referencia al subtipo correcto, de lo contrario podrían presentarse problemas en la manipulación posterior de los objetos de ese contenedor o tal vez ni siquiera sea legal añadir una variable tipo Object a un Container.

Shordi, si te parece prueba este camino e intentamos resolver los problemas que aparezcan.

Saludos.


-----------------------------------
shordi
Domingo, 12 Diciembre 2010, 20:51

Re: Clonar Controles
-----------------------------------
[quote]Si es así, podría ser un feature request que deberíamos solicitarle a Benoit, si evaluamos que es algo realmente necesario[/quote]
En mi caso no es necesario. Necesitaba una función que recorriese los controles de un contenedor y modificase las propiedades de algunos de ellos... pero con posibilidad de vuelta atrás. Se me ocurrió crear un objeto en tiempo de ejecución que fuese un clon del mismo para ello... y de ahí la pregunta.
Me metí en un berenjenal siguiendo algo parecido a lo que sugieres... (el problema está en lo que hay que poner donde tú pones "Setear objetos".. jejeje)
Al final no me gustó la solución y lo he hecho a base de "Clonar" las propiedades que me interesan recorriendo el .Children del contenedor. 
El único problema me lo encontré al descubrir que los contenedores pueden contener contenedores (¿quién los descontenedoreará?) y ahí he tenido la oportunidad de recurrir a la recursividad (¡toma expresión bonita!) por primera vez en un programa real.

Gracias por tu respuesta al post de IS CONTAINER, queda hasta bonito... jeje

Suerte


-----------------------------------
jsbsan
Domingo, 12 Diciembre 2010, 21:10

Re: Clonar Controles
-----------------------------------
fabianfv:

Apuntate para tu libro poner un ejemplo de esto, que no me enterado de nada...  :oops: :roll: 


Saludos.


-----------------------------------
fabianfv
Domingo, 12 Diciembre 2010, 23:18

Re: Clonar Controles
-----------------------------------
Julio:
[quote]
Apuntate para tu libro poner un ejemplo de esto, que no me enterado de nada... 
[/quote]
Gracias por la sugerencia.

Shordi:
[quote]
Me metí en un berenjenal siguiendo algo parecido a lo que sugieres... (el problema está en lo que hay que poner donde tú pones "Setear objetos".. jejeje) 
[/quote]
Sí, cuando lo piensas no es algo trivial, aunque probablemente tampoco sea algo tan complicado.

[quote]
El único problema me lo encontré al descubrir que los contenedores pueden contener contenedores (¿quién los descontenedoreará?)
[/quote]
Bueno, después de ese trabalenguas, un domingo a esta hora de la tarde, creo que me rindo por hoy :-)

[quote]
y ahí he tenido la oportunidad de recurrir a la recursividad (¡toma expresión bonita!) por primera vez en un programa real. 
[/quote]
Genial. Si te gusta la recursividad (¿a quien no le parecería elegante? ¿a un fan de C tal vez?) un paseo por Scheme, LISP, Haskell o algún otro lenguaje funcional te haría descubrir un parque de diversiones porque en FP se usa la recursividad con la misma frecuencia con la que uno respira :-)

Saludos.


-----------------------------------
shordi
Lunes, 13 Diciembre 2010, 11:42

Re: Clonar Controles
-----------------------------------
[quote] Si te gusta la recursividad (¿a quien no le parecería elegante? ¿a un fan de C tal vez?) un paseo por Scheme, LISP, Haskell o algún otro lenguaje funcional te haría descubrir un parque de diversiones porque en FP se usa la recursividad con la misma frecuencia con la que uno respira  [/quote]

No, gracias, entre Gambas, SQL (cons sus diferentes dialectos), HTML, php, CSS y demás... creo que estoy más que satisfecho. :mryellow:  :mryellow:


