Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   más buenas prácticas de programación (https://www.clubdelphi.com/foros/showthread.php?t=61548)

elcigarra 12-11-2008 11:47:40

más buenas prácticas de programación
 
Una consulta relacionada a otro hilo que comencé con este nombre, y referente a la liberación de la memoria. Alguien me puede explicar por qué no se puede hacer lo siguiente:
Código Delphi [-]
function TForm1.GetStrings:TStrings;
var
  miLista: TStrings;
begin
  miLista := TStringList.Create;
  miLista.Add('uno');
  miLista.Add('dos');
  Result := miLista;
  FreeAndNil(MiLista); // Esta linea da un error EAccessViolation
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
  memo1.Lines.Assign(GetStrings);
end;

Y sabiendo que no puede hacerse esto, como entonces puedo liberar la memoria de la variable miLista creada en esa función.

donald shimoda 12-11-2008 12:24:52

Cita:

Empezado por elcigarra (Mensaje 325478)
Y sabiendo que no puede hacerse esto, como entonces puedo liberar la memoria de la variable miLista creada en esa función.

Estas intentando devolver un objeto que destruyes en la linea posterior.

Opciones hay muchas,y no entiendo bien que queres hacer, pero como sea que lo hagas deberías destruir el objeto solo después de usarlo, es decir en el código que lo recibe. Ejemplo tosco:

Código Delphi [-]
procedure TForm1.GetStrings(var MyStrings:TStrings);
begin
  MyStrings.Clear;
  MyStrings.Add('uno');
  MyStrings.Add('dos');
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  miLista: TStrings;
begin
  miLista := TStringList.Create;
  GetStrings(miLista)
  memo1.Lines.Assign(miLista);
  FreeAndNil(MiLista); 
end;

Saludos

Caro 12-11-2008 13:26:34

Cita:

Empezado por donald shimoda (Mensaje 325483)
Estas intentando devolver un objeto que destruyes en la linea posterior.

Estoy de acuerdo con el amiguito Donald ;).

También podrías no crearte el TStrings y mandarle directo a tu función Memo.Lines que ya es un TStrings. Tu codigo quedaría así:

Código Delphi [-]
procedure TForm1.GetStrings(miLista : TStrings);
begin
  miLista.Add('uno');
  miLista.Add('dos');
end;
 
procedure TForm1.Button1Click(Sender: TObject);
begin
 GetStrings(Memo1.Lines);
end;

Saluditos

ElKurgan 12-11-2008 14:54:07

También te queda otra opción, como es el devolver los datos directamente como tipos de datos simples, puros y duros:

Código Delphi [-]
function TForm1.GetStrings:String;
var
  miLista: TStrings;
begin
  miLista := TStringList.Create;
  try  miLista.Add('uno');
    miLista.Add('dos');
    Result := miLista.Text;
  finally
    FreeAndNil(MiLista);
  end
end;
  
procedure TForm1.Button1Click(Sender: TObject);
begin 
  memo1.Lines.Text := GetStrings;
end;

Un saludo

ElKurgan 12-11-2008 14:55:29

ARGH... Pero... ¿Que le pasa a mi editor?

Mil perdones

DarkMan 12-11-2008 14:56:29

TStringList es una clase TObject, la variable no contiene la clase en sí, sino su referencia. Esto quiere decir que es un puntero a la dirección de memoria en la que se contiene ese objeto.

En esa función lo que haces es devolver el puntero a una dirección de memoria que contiene el objeto que tu has destruido en la misma función, por ello te salta el error. En todo caso, si deseas seguir con esa sintaxis debería ser así el código:
Código Delphi [-]
function TForm1.GetStrings:TStrings;
var
  miLista: TStrings;
begin
  miLista := TStringList.Create;
  miLista.Add('uno');
  miLista.Add('dos');
  Result := miLista;
{  FreeAndNil(MiLista); // Esta linea da un error EAccessViolation}
end;
procedure TForm1.Button1Click(Sender: TObject);
var MiLista: TStrings;
begin
 MiLista:= GetStrings;  
 memo1.Lines.Assign(MiLista);
 FreeAndNil(MiLista);
 {Ahora ya has liberado el objeto creado en la función anterior}
end;

ContraVeneno 12-11-2008 15:49:35

¿por qué no seguir el ejemplo que viene en la ayuda de delphi?
Es decir, en el ejemplo de la ayuda de delphi, la última línea dice:
MyList.Free
no utilizan FreeAndNil....
Así que esto no debería darte problemas:
Código Delphi [-]
...
 miLista := TStringList.Create; 
 miLista.Add('uno'); 
 miLista.Add('dos'); 
 Result := miLista;   
 MiLista.Free; 
...

Aunque me gusta más lo que propone Caro, digo, si ya tienes un stringlist, ¿para qué crear otro?

donald shimoda 12-11-2008 16:00:20

Cita:

Empezado por ContraVeneno (Mensaje 325530)

Así que esto no debería darte problemas:
Código Delphi [-]
...
 miLista := TStringList.Create; 
 miLista.Add('uno'); 
 miLista.Add('dos'); 
 Result := miLista;   
 MiLista.Free; 
...

Amigo, repites el error del pimer post. Freeandnil solo hace

Código Delphi [-]
if Assigned(x) then
  x.free;
Es decir valida que solo libera cuando esta creado. Es codigo seguro.

Lo que tu colocas da problemas porque sigues liberando un objeto que pretendes devolver.

Saludos.

donald shimoda 12-11-2008 16:02:50

Cita:

Empezado por DarkMan (Mensaje 325513)
{Ahora ya has liberado el objeto creado en la función anterior}

El problema de esto es que no tiene sentido crear un objeto en una función y liberarlo en otra. Por que? Porque en este caso una función es totalmente dependiente de la otra. Entonces para que separarlas?

Saludos.

Lepe 12-11-2008 16:06:57

Desde mi punto de vista, no es buena idea que una rutina interna cree un objeto y que después sea el usuario del módulo el que deba destruirlo. Si ha de hacerse así, hay que documentarlo muy bien.

Lo que yo haría:
Código Delphi [-]
function TForm1.SetStringsTo(var milista:TStrings);
begin
  if not Assigned(milista) then
     raise Exception.Create('proc TForm1.GetStrings:Se necesita una lista  creada');
  miLista.Add('uno');
  miLista.Add('dos');
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  SetStringsTo(memo1.lines);  
end;

Hay que guardar la semántica en delphi, dicho de otra forma, si veo este código dentro de 1 año:
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
var MiLista: TStrings;
begin
 MiLista:= GetStrings;  
 memo1.Lines.Assign(MiLista);
 FreeAndNil(MiLista);
 {Ahora ya has liberado el objeto creado en la función anterior}
end;
Lo primero que digo es: " MiLista no ha sido creado", ahora tengo que buscar la implementación de GetStrings y ver si dentro se llama a Milista.Create.

Lo correcto según mi opinión es:

Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
var MiLista: TStrings;
begin
 MiLista:= TStringList.Create;
 GetStrings(Milista);
 FreeAndNil(MiLista);
end;
dentro de esa rutina queda claro que has creado un TStringList y lo estás liberando, no hay dudas. Ten en cuenta que TStrings es una clase con descendientes, por tanto milista puede ser un TstringList, TMemoStrings, TComboboxStrings, etc., todos ellos son compatibles porque heredan de TStrings, pero no son iguales. En ese código, dejas claro que se trata de un TStringList.

Por cierto, el nombre de la rutina, "GetStrings", me parece ambiguo, (ya sé que es sólo un ejemplo, pero en fin, a ver si me explico...) si dentro de GetStrings estoy añadiendo elementos a la variable "MiLista" yo le cambiaría el nombre, por algo así como "AddItemsTo(Milista)".

Saludos

Caro 12-11-2008 16:07:12

Cita:

Empezado por ContraVeneno (Mensaje 325530)
¿por qué no seguir el ejemplo que viene en la ayuda de delphi?
Es decir, en el ejemplo de la ayuda de delphi, la última línea dice:
MyList.Free

Te daría el mismo error amiguito, ya que se estaría liberando antes de hacerle el Assign a la Lines del Memo.

Por lo menos yo cuando libero un TStringList lo hago con FreeAndNil, porque, digamos que tengo un tStringList como variable global en mi Unit. Cuando libero con Free y en otro lugar hago esto:

Código Delphi [-]
 if Assigned(Lista) then
  //Si existe quiero obtener su contenido

Al no haberlo hecho con FreeAndNil habiendolo liberado antes me sale un accessViolation, por eso lo libero con FreeAndNil.

Saluditos

ContraVeneno 12-11-2008 16:13:45

ya, me guíe por el ejemplo de Delphi, no me había fijado que era una función que tendría que regresar ese valor.

Lepe 12-11-2008 17:25:59

Resumiendo:
Si vas a reutilizar una variable varias veces (crearla en memoria y liberarla) es mejor usar FreeAndNil.

Si sólo vas a crear y destruir la variable una vez, puedes usar variable.Free;

Saludos

Al González 12-11-2008 17:47:10

¡Hola!

Cita:

Empezado por donald shimoda (Mensaje 325531)
...Freeandnil solo hace

Código Delphi [-]
if Assigned(x) then
  x.free;
Es decir valida que solo libera cuando esta creado. Es codigo seguro...

Disculpa que te corrija Donald, pero eso no es lo que hace FreeAndNil. Linett ha dado una explicación más cierta; la variable objeto queda con un valor en blanco (Nil) tras su liberación con FreeAndNil. Es el propio método Free el que hace una validación de seguridad antes de llamar al destructor Destroy.

Como ya se dijo, es normal utilizar FreeAndNil con variables globales, y aunque también puede ser aplicado a variables locales, por lo general sólo utilizamos Free con éstas. En otras palabras, el uso de FreeAndNil se justifica cuando existe la posibilidad de que alguna parte del código intente hacer algo con la instancia de objeto apuntada por la variable después de haberse destruido dicha instancia.

Por otro lado, la solución propuesta por Linett al principio me parece la más adecuada. Cuando mucho haría falta una llamada al método Clear antes del primer Add. ;)

Un abrazo sin destruir.

Al González. :)

donald shimoda 12-11-2008 18:03:47

Cita:

Empezado por Al González (Mensaje 325559)
¡Hola!

Disculpa que te corrija Donald, pero eso no es lo que hace FreeAndNil. Linett ha dado una explicación más cierta; la variable objeto queda con un valor en blanco (Nil) tras su liberación con FreeAndNil. Es el propio método Free el que hace una validación de seguridad antes de llamar al destructor Destroy.

Tenes absolutamente razón, lo escribí rápido y me olvide que en realidad soy yo el que hago siempre:

Código Delphi [-]
if Assigned(x) then
  FreeAndNil(x);

Esto segun Allen Bauer es un vicio horrendo de programación . Ahora si mirás el código delhi de FreeAndNil:

Código Delphi [-]
procedure FreeAndNil(var Obj);
var
  Temp: TObject;
begin
  Temp := TObject(Obj);
  Pointer(Obj) := nil;
  Temp.Free;
end;

Si obj = nil estas llamando a nil.free!!!! No jodamos, es inaceptable o muy arriesgado para mis pareceres. Aunque se enoje Allen Bauer , escucho argumentos en contra que me quiten el vicio. :D

Saludos

roman 12-11-2008 18:35:09

Cita:

Empezado por donald shimoda (Mensaje 325561)
Si obj = nil estas llamando a nil.free!!!! No jodamos, es inaceptable o muy arriesgado para mis pareceres.

Al contrario. Como comenta Al, es el código de Free (ojo, no el de FreeAndNil) el que verifica que la referencia no sea nil.

Código Delphi [-]
procedure TObject.Free;
begin
  if Self <> nil then
    Destroy;
end;

Justo por eso (y sólo por eso) es que siempre se recomienda usar Free en lugar de Destroy.

// Saludos

donald shimoda 12-11-2008 19:42:03

Cita:

Empezado por roman (Mensaje 325566)
Al contrario. Como comenta Al, es el código de Free (ojo, no el de FreeAndNil) el que verifica que la referencia no sea nil.

Al contrario de que? No dije lo contrario, mira mas abajo.:)

Código Delphi [-]procedure TObject.Free; begin if Self <> nil then Destroy; end;


Justo por eso (y sólo por eso) es que siempre se recomienda usar Free en lugar de Destroy.

// Saludos[/quote]

Y te parece segura una llamada como Nil.free ????

Este tema incluso esta referenciado en el blog de Allen Bauer, no todos estan convencidos de una u otra manera. Para mi entre código raro y código seguro : siempre seguro. Eso me permite que un servidor corra 24 horas sin un solo problema.

Saludos.

Al González 12-11-2008 19:55:03

Cita:

Empezado por donald shimoda (Mensaje 325584)
...Y te parece segura una llamada como Nil.free ????...

En Delphi es de lo más seguro, Donald. ;)

Cuando el objeto es Nil y el método Free hace esta validación:

Código Delphi [-]
if Self <> nil then
,

está preguntando si Nil es diferente de Nil, en cuyo caso llama a Destroy. De lo contrario no hace absolutamente nada. Si Free fuese un método virtual o hiciera alguna otra cosa con la "improbable" instancia, entonces sí sería inadecuado usarlo en esos casos.

Self es un parámetro implícito que llevan todos los métodos y equivale al puntero en sí de la instancia en cuestión. Nil, cuando el puntero está en blanco. No hay absolutamente ningún problema. :)

¿Ya convencido? :p

roman 12-11-2008 20:05:01

Tal como dice Al. Es completamente seguro usar Free en nil. Ese es el objetivo de Free, que sea seguro usarlo. Y lo es porque nunca hay una llamada a nil.Destroy.

// Saludos

roman 12-11-2008 20:17:56

A ver, borrón y cuenta nueva.

Creo que ya veo por donde va la preocupación de Donald. A él no le inquieta la llamada a Destroy, sino la misma llamada a nil.Free.

Pero creo que hay que recordar que un objeto no es un record. ¿Qué pasa cuando se llama nil.Free? El compilador genera esta llamada:

Código:

mov eax, [eax + ...]
call TObject.Free

Esto es, la función que se llama es TObject.Free que vive en algún lugar de la tabla de métodos de la clase (no el objeto) TObject. Aquí no hay problema entonces, porque TObject existe independientemente de sus instancias. Y a Free se le pasa el parámetro Self que menciona Al, que es la instancia a la que se le aplica el método. Y es ya Free el que protege la llamada al destructor.

// Saludos

donald shimoda 12-11-2008 20:30:03

Cita:

Empezado por Al González (Mensaje 325590)
En Delphi es de lo más seguro, Donald. ;)

Cuando el objeto es Nil y el método Free hace esta validación:

Código Delphi [-]if Self <> nil then

,

está preguntando si Nil es diferente de Nil, en cuyo caso llama a Destroy. De lo contrario no hace absolutamente nada. Si Free fuese un método virtual o hiciera alguna otra cosa con la "improbable" instancia, entonces sí sería inadecuado usarlo en esos casos.

Self es un parámetro implícito que llevan todos los métodos y equivale al puntero en sí de la instancia en cuestión. Nil, cuando el puntero está en blanco. No hay absolutamente ningún problema. :)

¿Ya convencido? :p

La verdad con tu explicación para nada ya que no me contas nada nuevo. :rolleyes:
Estas explicándome que hace el código y que es self :p:p:p:p.
Lo que quiero saber es porque razón un puntero a la nada (nil) es seguro.

Saludos.

roman 12-11-2008 20:37:23

De hecho (aunque no lo voy a jurar :)) esto es seguro:

Código Delphi [-]
type
  TPersona = class
    procedure Saluda;
  end;

procedure TPersona.Saluda;
begin
  ShowMessage('Hola');
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Persona: TPersona;

begin
  // No construyo el objeto
  Persona.Saluda;
end;

// Saludos

donald shimoda 12-11-2008 20:40:46

Cita:

Empezado por roman (Mensaje 325598)
A ver, borrón y cuenta nueva.

Creo que ya veo por donde va la preocupación de Donald. A él no le inquieta la llamada a Destroy, sino la misma llamada a nil.Free.

Exacto.

Cita:

Empezado por roman (Mensaje 325598)
Pero creo que hay que recordar que un objeto no es un record. ¿Qué pasa cuando se llama nil.Free? El compilador genera esta llamada:

Código:

mov eax, [eax + ...]
call TObject.Free

Esto es, la función que se llama es TObject.Free que vive en algún lugar de la tabla de métodos de la clase (no el objeto) TObject. Aquí no hay problema entonces, porque TObject existe independientemente de sus instancias. Y a Free se le pasa el parámetro Self que menciona Al, que es la instancia a la que se le aplica el método. Y es ya Free el que protege la llamada al destructor.

// Saludos

Tenes razón, aunque a simple vista parezca voladura.

Para agregar a la charla y enriquecerla , un post sobre los efectos colaterales de la forma en que esta implementado, sobre todo cuando usas tareas:

link

Saludos.

donald shimoda 12-11-2008 20:42:44

Cita:

Empezado por roman (Mensaje 325603)
De hecho (aunque no lo voy a jurar :)) esto es seguro:

Código Delphi [-]type TPersona = class procedure Saluda; end; procedure TPersona.Saluda; begin ShowMessage('Hola'); end; procedure TForm1.Button1Click(Sender: TObject); var Persona: TPersona; begin // No construyo el objeto Persona.Saluda; end;


// Saludos

Jeje, hasta que deje de serlo. ;)

FPC se queja con ese código, por lo tanto prefiero escribir código seguro que experimenta con lo que se banca la VCL. :)

Saludos

roman 12-11-2008 20:54:23

Cita:

Empezado por donald shimoda
prefiero escribir código seguro

Nosotros también, pero también preferimos no redundar. No hace falta evitar el caso nil por lo que expliqué arriba.

En el ejemplo anterior, la llamada Persona.Saluda realmente genera este código:

Código:

call TPersona.Saluda
Se llama a una función que existe, no hay una referencia a una memoria inválida.

Si tuviéramos

Código Delphi [-]
type
  TPersona = class
    Saludo: String;
    procedure Saluda;
  end;

procedure TPersona.Saluda;
begin
  ShowMessage(Saludo);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Persona: TPersona;

begin
  // No construyo el objeto
  Persona.Saluda;
end;

entonces sí que habría problemas, porque no ha sido asignada memoria a ningún objeto y por tanto el campo Persona.Saludo no existe aún.

// Saludos

Lepe 12-11-2008 21:13:56

... me están estressanndo :D

;)

Sal%&(/% Invalid pointer operation.

roman 12-11-2008 21:27:42

Por eso lo tengo comentado:

// Saludos

no vaya a ser... :D

// Saludos

Delphius 12-11-2008 21:30:11

Al igual que lepe me dejaron frito el cerebro.:o:confused:

Leí el link que señala Donald y la verdad es que no lo entendí:( ¿Dónde está el problema?:confused:

Saludos,

Al González 12-11-2008 21:41:43

Cita:

Empezado por donald shimoda (Mensaje 325601)
...Lo que quiero saber es porque razón un puntero a la nada (nil) es seguro...

Ya, ahora veo, al igual que Román, que lo que te preocupa es en sí el uso de una falsa instancia cuando su apuntador es Nil.

Tratándose de objetos, debes recordar que el código compilado de las rutinas (métodos) se guarda en ubicaciones de memoria distintas a donde se alojan los campos de datos de una instancia. De hecho, por dentro, el bloque de memoria que ocupa una instancia de objeto es meramente una "estructura" del estilo Record, teniendo un primer "campo" invisible que guarda un apuntador a donde se encuentra definida la clase a la que pertenece, su herencia, métodos y otros elementos de RTTI.

El código compilado está disponible para el programa desde que arranca la aplicación, así que los métodos que el compilador incluyó en el programa ejecutable pueden (mas no necesariamente "deben") ser llamados sin necesidad de usar una instancia real de por medio, como bien lo ejemplificó Román más arriba.

Lo inseguro es hacer esto con un método que emplee uno de los campos de la instancia o algún otro dato de memoria cuya disponibilidad (existencia) dependa de que el objeto sea "real", como ya también lo ejemplificó Román.

El método Free no "toca" nada de la memoria de datos. Se limita a preguntar si Self es otra cosa distinta de Nil, para luego llamar al destructor con seguridad. Por ello es que no preocupa su uso con un objeto Nil. Fue concebido tal como es para que el programador no tuviese que preguntar si una variable objeto es Nil antes de intentar liberar dicho objeto.

Cita:

Empezado por donald shimoda (Mensaje 325607)
...un post sobre los efectos colaterales de la forma en que esta implementado, sobre todo cuando usas tareas:

link...

Esa referencia es harina de otro costal. Si no me equivoco (mi inglés es lento), habla del conflicto que presenta la función FreeAndNil cuando se intenta hacer referencia a la variable objeto durante la destrucción del mismo, momento en el cual tal variable ya tiene asignado un valor de Nil.

Cita:

Empezado por donald shimoda (Mensaje 325608)
...FPC se queja con ese código, por lo tanto prefiero escribir código seguro que experimenta con lo que se banca la VCL. :)...

No le encuentro sentido a esto último que dices, ¿podrías explicarte, por favor? :)

Espero haber ayudado a esclarecer un poco el asunto.

Saludos a todos y no se estresen porque me estreso. :p

Al.

P.D. Cabe mencionar que la llamada a métodos virtuales con un objeto Nil sí es totalmente inviable y en todos los casos elevará una excepción. Porque, para hacer el late binding, se necesita conocer cuál es la clase real de la instancia, es decir, leer ese primer campo invisible que está alojado en los primeros cuatro bytes de la memoria del objeto. Siendo el objeto Nil (dirección de memoria 0), no hay tal dato. En todo caso el programa intentará leer los primeros cuatro bytes de la RAM, posición de memoria no accesible. Free NO es virtual, carecería de sentido si lo fuera.

donald shimoda 12-11-2008 21:51:46

Cita:

Empezado por Al González (Mensaje 325627)
Esa referencia es harina de otro costal. Si no me equivoco (mi inglés es lento), habla del conflicto que presenta la función FreeAndNil cuando se intenta hacer referencia a la variable objeto durante la destrucción del mismo, momento en el cual tal variable ya tiene asignado un valor de Nil.

A pesar de tu inglés entendiste bien. O casi, porque decís que es harina de otro costal? :rolleyes:

Cita:

Empezado por Al González (Mensaje 325627)

No le encuentro sentido a esto último que dices, ¿podrías explicarte, por favor? :)

Al.

FPC no acepta el uso del código escrito por román, Probalo.

Saludos

roman 12-11-2008 22:02:47

Cita:

Empezado por Al González (Mensaje 325627)
Tratándose de objetos, debes recordar que el código compilado de las rutinas (métodos) se guarda en ubicaciones de memoria distintas a donde se alojan los campos de datos de una instancia. De hecho, por dentro, el bloque de memoria que ocupa una instancia de objeto es meramente una "estructura" del estilo Record, teniendo un primer "campo" invisible que guarda un apuntador a donde se encuentra definida la clase a la que pertenece, su herencia, métodos y otros elementos de RTTI.

No sé porqué, pues es sólo una esquema, pero eso que explicas Al, a mi se me quedó muy grabado con esta imagen




del libro Delphi in a Nutshell de Ray Lischner

Cita:

Empezado por Al González (Mensaje 325627)
No le encuentro sentido a esto último que dices, ¿podrías explicarte, por favor? :)

Bueno, Delphi también protesta:

Cita:

[Warning] Unit1.pas(41): Variable 'Persona' might not have been initialized
aunque no lo impide. Desde luego tiene sus riesgos usarlo regularmente como si fuese una característica del lenguaje. Pero en el caso que nos ocupa, como ya se ha visto, es perfectamente seguro.

// Saludos

ContraVeneno 12-11-2008 22:03:59

¿ que es nil ? :confused::confused:

jojojojo

roman 12-11-2008 22:10:23

Cita:

Empezado por ContraVeneno (Mensaje 325635)
¿ que es nil ? :confused::confused:

Aquí su origen:

http://www.heideggeriana.com.ar/textos/nihilismo_3.htm

ja, ja, ja

// Saludos

ContraVeneno 12-11-2008 22:13:59

changos, era broma maese Roman :p :D

Delphius 12-11-2008 22:24:41

Cita:

Empezado por Al González (Mensaje 325627)

Esa referencia es harina de otro costal. Si no me equivoco (mi inglés es lento), habla del conflicto que presenta la función FreeAndNil cuando se intenta hacer referencia a la variable objeto durante la destrucción del mismo, momento en el cual tal variable ya tiene asignado un valor de Nil.

No le encuentro sentido a esto último que dices, ¿podrías explicarte, por favor? :)

Espero haber ayudado a esclarecer un poco el asunto.

Saludos a todos y no se estresen porque me estreso. :p

Te agradezco Al, por aclarar (y aclararme de paso;)) las cosas. Ya mi brain estaba por hacer ¡PUM!. Y mi inglés es super lento... El haber leído singleton por aqui, y allí provocó unos cuantos corto circuitos. ¡Me mete patrones donde no hay!:D

Ahora si, a ver si la consola de mi cabeza empieza a mandar comandos PANIC OFF.:):p:D

Saludos,

Al González 12-11-2008 22:31:27

Cita:

Empezado por donald shimoda (Mensaje 325630)
...porque decís que es harina de otro costal? :rolleyes:

Porque el punto de la discusión donde hiciste esa referencia («un post sobre los efectos colaterales de la forma en que esta implementado, sobre todo cuando usas tareas») era que no entendías o no dabas por válido el uso del método Free con un objeto Nil. Como si ese artículo de Miller pudiera llevarnos a concluir que la práctica del "ObjetoNil.Free" fuese algo desaconsejable.

Cita:

Empezado por donald shimoda (Mensaje 325630)
...FPC no acepta el uso del código escrito por román, Probalo...

Quizá pregunte una estupidez, pero ¿qué es FPC? Google me llevó a la página del Fútbol Profesional Colombiano. :confused:

Mi pregunta se refería a eso de «prefiero escribir código seguro que experimenta con lo que se banca la VCL».

En espera de tus apreciaciones.

Saludos.

Al González. :)

donald shimoda 12-11-2008 22:40:49

Cita:

Empezado por Al González (Mensaje 325643)
Porque el punto de la discusión donde hiciste esa referencia («un post sobre los efectos colaterales de la forma en que esta implementado, sobre todo cuando usas tareas») era que no entendías o no dabas por válido el uso del método Free con un objeto Nil. Como si ese artículo de Miller pudiera llevarnos a concluir que la práctica del "ObjetoNil.Free" fuese algo desaconsejable.

No, como bien dice el texto lo que trae complicaciones es la manera en que esta implementado FreeAndNil, si no se toman las medidas del caso al accesarlo desde varias tareas.

Cita:

Empezado por Al González (Mensaje 325643)
Quizá pregunte una estupidez, pero ¿qué es FPC? Google me llevó a la página del Fútbol Profesional Colombiano. :confused:

:p:p:p Free Pascal Compiler.

Cita:

Empezado por Al González (Mensaje 325643)
Mi pregunta se refería a eso de «prefiero escribir código seguro que experimenta con lo que se banca la VCL».

Exacto, me refería a que prefiero escribir código que cualquier compilador pascal acepte, no solo Delphi.

Saludos.

Al González 12-11-2008 22:44:42

Cita:

Empezado por roman (Mensaje 325634)
...No sé porqué, pues es sólo una esquema, pero eso que explicas Al, a mi se me quedó muy grabado con esta imagen




del libro Delphi in a Nutshell de Ray Lischner...

Un bello esquema, sin duda. Si mal no recuerdo yo lo aprendí de la ayuda de Turbo Pascal y después lo reforcé con la ayuda de Delphi. Me parecía entonces muy interesante todo lo que los ingenieros de software hacían para abrirle paso en la historia a la fabulosa POO que hoy día disfrutamos. :)

Además, leer tanto texto sin Internet y un diccionario en la mano me ayudó a conseguir mis primeras nociones reales del idioma inglés.

Un abrazo esquemático y textual.

Al González. :)

Al González 12-11-2008 23:12:21

Cita:

Empezado por donald shimoda (Mensaje 325644)
No, como bien dice el texto lo que trae complicaciones es la manera en que esta implementado FreeAndNil, si no se toman las medidas del caso al accesarlo desde varias tareas...

Bueno, eso mismo ya se había mencionado. Y aunque no se trate de una aplicación multihilo el problema es susceptible de presentarse según comenté más arriba. Pero sigo sin comprender qué tiene que ver esto con tu desapego al uso de ObjetoNil.Free.

Cita:

Empezado por donald shimoda (Mensaje 325644)
...:p:p:p Free Pascal Compiler.
Exacto, me refería a que prefiero escribir código que cualquier compilador pascal acepte, no solo Delphi...

Sabía que te causaría gracia, romper el hielo no es malo. :p

Ahora sé qué es FPC. Pero entonces acláranos una cosa por favor, ¿Free Pascal Compiler no acepta ese uso del método Free, que en Delphi es de lo más estable, tradicional, útil y seguro? :confused:

Y si realmente sí es aceptado por FPC, al contrario de lo que das a entender, ¿no sería mejor que externaras tus conclusiones claras y reales respecto al empleo del método Free con objetos Nil, una vez consideradas las explicaciones dadas en mensajes anteriores? De lo contrario, algunos lectores futuros del este hilo podrían albergar dudas respecto a la validez y seguridad de usar ObjetoNil.Free. En buen plan. :)

Un abrazo por la verdad.

Al González.

donald shimoda 12-11-2008 23:24:10

Cita:

Empezado por Al González (Mensaje 325653)
Pero sigo sin comprender qué tiene que ver esto con tu desapego al uso de ObjetoNil.Free.

Nada amigo, solo fue un comentario relacionado al tema, hasta donde quieres llegar?

Cita:

Empezado por Al González (Mensaje 325653)
Sabía que te causaría gracia, romper el hielo no es malo. :p

Ahora sé qué es FPC. Pero entonces acláranos una cosa por favor, ¿Free Pascal Compiler no acepta ese uso del método Free, que en Delphi es de lo más estable, tradicional, útil y seguro? :confused:

Y si realmente sí es aceptado por FPC, al contrario de lo que das a entender, ¿no sería mejor que externaras tus conclusiones claras y reales respecto al empleo del método Free con objetos Nil, una vez consideradas las explicaciones dadas en mensajes anteriores? De lo contrario, algunos lectores futuros del este hilo podrían albergar dudas respecto a la validez y seguridad de usar ObjetoNil.Free. En buen plan. :)

Un abrazo por la verdad.

Al González.

Ja, y siempre se llega a lo mismo. Gracias maestro. :p:p:p:p


La franja horaria es GMT +2. Ahora son las 05:27:29.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi