Delphi 5: Ideas para simular & # 8220; Obsoleto & # 8221; o & # 8220; en desuso & # 8221; métodos?

StackOverflow https://stackoverflow.com/questions/436896

  •  22-07-2019
  •  | 
  •  

Pregunta

Quiero marcar un método como obsoleto, pero Delphi 5 no tiene esa característica.

Por el bien de un ejemplo, aquí hay un método inventado con su forma desaprobada y nueva preferida:

procedure TStormPeaksQuest.BlowHodirsHorn; overload; //obsolete
procedure TStormPeaksQuest.BlowHodirsHorn(UseProtection: Boolean); overload;

Nota: para este ejemplo hipotético, asumimos que usar la versión sin parámetros es simplemente malo. Hay problemas con no " usar protección " - Que no tienen una buena solución. A nadie le gusta tener que usar protección, pero nadie quiere no usar protección. Por lo tanto, hacemos que la persona que llama decida si desea usar protección o no cuando toca el cuerno de Hodir . Si predeterminamos la versión sin parámetros para continuar no usando protección:

procedure TStormPeaksQuest.BlowHodirsHorn;
begin
    BlowHodirsHorn(False); //No protection. Bad!
end;

entonces el desarrollador está en riesgo de todo tipo de cosas desagradables. Si forzamos la versión sin parámetros para usar protección:

procedure TStormPeaksQuest.BlowHodirsHorn;
begin
    BlowHodirsHorn(True); //Use protection; crash if there isn't any
end;

entonces existe la posibilidad de problemas si el desarrollador no obtuvo ninguna protección o no posee ninguna.

Ahora podría cambiar el nombre del método obsoleto:

procedure TStormPeaksQuest.BlowHodirsHorn_Deprecatedd; overload; //obsolete
procedure TStormPeaksQuest.BlowHodirsHorn(UseProtection: Boolean); overload;

Pero eso provocará un error de compilación, y la gente se molestará conmigo (y realmente no quiero escuchar sus quejas). quiero que obtengan un fastidio , en lugar de un error real.

pensé en agregar una afirmación:

procedure TStormPeaksQuest.BlowHodirsHorn; //obsolete
begin
   Assert(false, 'TStormPeaksQuest.BlowHodirsHorn is deprecated. Use BlowHodirsHorn(Boolean)');

   ...
end;

Pero no puedo garantizar que el desarrollador no envíe una versión sin afirmaciones, lo que provocará un bloqueo desagradable para el cliente .

pensé en usar solo lanzar una aserción si el desarrollador está depurando:

procedure TStormPeaksQuest.BlowHodirsHorn; //obsolete
begin
   if DebugHook > 0 then
      Assert(false, 'TStormPeaksQuest.BlowHodirsHorn is deprecated. Use BlowHodirsHorn(Boolean)');

   ...
end;

Pero realmente no quiero causar un accidente en absoluto.

pensé en mostrar un MessageDlg si están en el depurador (que es una técnica que he hecho en el pasado):

procedure TStormPeaksQuest.BlowHodirsHorn; //obsolete
begin
   if DebugHook > 0 then
        MessageDlg('TStormPeaksQuest.BlowHodirsHorn is deprecated. Use BlowHodirsHorn(Boolean)', mtWarning, [mbOk], 0);

   ...
end;

pero eso sigue siendo muy perjudicial. Y ha causado problemas en los que el código está atascado al mostrar un diálogo modal, pero el cuadro de diálogo obviamente no era visible.

Esperaba algún tipo de mensaje de advertencia que los molestara, hasta que saquen sus ojos y finalmente cambien su código.

Pensé que quizás si añadía una variable no utilizada:

procedure TStormPeaksQuest.BlowHodirsHorn; //obsolete
var
   ThisMethodIsObsolete: Boolean;
begin
   ...
end;

Esperaba que esto causara una pista solo si alguien hacía referencia al código. Pero Delphi muestra una pista, incluso si no llama en realidad use el método obsoleto.

¿Alguien puede pensar en otra cosa?

¿Fue útil?

Solución 2

Lo que terminé usando fue una combinación de optar por un sistema en el que acepta no tener ningún código en desuso, con cadenas de depuración de salida y puntos de interrupción de lo contrario.

Al igual que estricto html, he creado una definición Strict .

Todas las unidades comunes tienen el código obsoleto definido si se define Strict . De esta forma, el desarrollador acordó que no tendrán código obsoleto en su proyecto:

{$IFNDEF Strict}
procedure TStormPeaksQuest.BlowHaldirsHorn; overload; //obsolete
{$ENDIF}
procedure TStormPeaksQuest.BlowHaldirsHorn(UseProtection: Boolean); {$IFNDEF Strict}overload;{$ENDIF}


{$IFNDEF Strict}
procedure TStormPeaksQuest.BlowHaldirsHorn; //obsolete
begin
   OutputDebugString(PAnsiChar('TStormPeaksQuest.BlowHaldirsHorn is deprecated. Use BlowHaldirsHorn(Boolean)'));

   //Don't debugbreak without a debugger attached!
   if DebugHook > 0 then
        Windows.DebugBreak;

   ...
end;

Por lo tanto, si el desarrollador quiere tener el código apropiado, sufriendo tener que realizar cambios de código cuando las cosas nuevas están en desuso, pueden:

{$DEFINE Strict}

Si no, entonces siempre habrá un OutputDebugString, y cualquiera con Vista de depuración puede ver (incluso clientes). Es divertido ver software comercial (incluso el de Microsoft) con cadenas de depuración de salida sobrantes.

Y finalmente, si hay un depurador adjunto, obtendrán un punto de interrupción de depuración de la nada. Si alguien pregunta, puedo aprovechar esa oportunidad para burlarme de ellos.

Otros consejos

¿Qué tal algo como

procedure TStormPeaksQuest.BlowHaldirsHorn; //obsolete
begin
  if DebugHook > 0 then asm int 3 end;  
  // This method is Obsolete!  Use XXXXX instead.
  Abort; // Optional, makes method useless  
  // old code here . . . 
end;

Una especie de compromiso entre una afirmación y un mensaje de presentación. El desarrollador solo necesita presionar F9 para continuar. Podrías poner un aborto, y luego el método no haría nada, y eso los obligaría a cambiar de método y la interrupción los hace conscientes de ello.

Personalmente, recomendaría actualizar a una versión más nueva de Delphi. 2007 y 2009 son excelentes lanzamientos y realmente valen la pena la actualización.

Esto no responde exactamente a su pregunta, pero podría proporcionar una solución alternativa. ¿No podría actualizar la función original con un valor predeterminado ...

procedure TStormPeaksQuest.BlowHaldirsHorn(UseProtection: Boolean = False);

... para que el código heredado se compile y se comporte igual, pero la nueva funcionalidad está disponible para los nuevos desarrolladores.

¿Por qué quieres hacer esto y por qué no quieres actualizar la versión de Delphi?

Sin la etiqueta obsoleta, realmente no tiene una opción limpia para filtrar el uso de métodos obsoletos. Por lo tanto, depende de dónde desea hacer la concesión:

  • el cambio de nombre detecta el error en tiempo de compilación (a menos que haya otro método / función con el mismo nombre dentro del alcance).
  • todos los demás métodos solo se capturan en tiempo de ejecución. Y esto tiene el riesgo de caer en el código de producción.

Lo que puede hacer es crear un registro obsoleto. Esto no molestará a nadie, y no es un desastre completo si ingresa el código de producción. Pero si sus pruebas tienen cobertura completa, atrapará a todos los culpables. Solo tiene que verificar el archivo de registro después de una ejecución (prueba).

Y, por supuesto, la mejor manera es utilizar grep para encontrar todas las ocurrencias del código y cambiarlo.

Estoy de acuerdo con un parámetro opcional si hará el trabajo. Pero puedo pensar en situaciones en las que los parámetros opcionales no encajan. Por ejemplo, he movido funciones a nuevas unidades, pero conservé las antiguas y las marqué como obsoletas.

Supongo que la solución que elija dependerá también de la disciplina de su equipo. ¿Se dan cuenta activamente y trabajan para corregir todas las sugerencias y advertencias para sus aplicaciones? Espero que sí, pero me da vergüenza admitir que el equipo con el que trabajo (incluido yo mismo) no se mantiene al tanto de todas las sugerencias y advertencias. De vez en cuando reparo la mayor cantidad de pistas & amp; advertencias según lo permita el tiempo y debemos corregirlas, pero en realidad tenemos que hacer el trabajo y estamos más centrados en las nuevas características y plazos.

Entonces, mi punto es, incluso si pudiera marcarlos como obsoletos o dar una pista / advertencia similar, ¿cree que su equipo se tomará el tiempo de cambiar su código de todos modos?

No es una solución total ya que no puede diferenciar si han utilizado el método o no, pero si está disponible en Delphi 5, pero podría usar el $ MESSAGE directiva del compilador para emitir una advertencia en tiempo de compilación.

Nada dice "¡Arreglame!" como un compilador de descanso.
Dicho esto, tengo un colega que modifica regularmente las firmas de las rutinas de 'código común' ... ¡y sí, es molesto!

Mi enfoque preferido (es decir, nuestro equipo aún no está allí: /) es el siguiente:

  1. Todos los desarrolladores deben poder realizar fácilmente una compilación completa de todos los proyectos en sus propias máquinas.
  2. Quien decida cambiar el código común debe asumir la responsabilidad de las consecuencias. Es decir. Repara todo el código afectado.
    • De acuerdo, a veces dicho desarrollador puede no ser ideal para implementar y verificar todas las correcciones correctamente.
    • Pero, por la misma razón, los desarrolladores se impusieron a "adoptar el nuevo contrato". en su propio código podría no estar claro sobre las sutilezas del nuevo contrato. Es decir.
      • ¿Hay algo especial que deba hacerse para usar la protección?
      • ¿Cómo se implementa el uso de la protección?
      • ¿Cuáles son las preocupaciones sobre cómo podría romper el código existente?
    • Esta es una razón importante por la que es importante un conjunto completo de casos de prueba.
  3. Generalmente, desea aplicar el efecto dominó de todos los cambios lo antes posible. Es decir. Si bien los detalles más finos del cambio están frescos en la mente del desarrollador de origen, ¡antes de que la atención cambie a otra cosa!
  4. Debería ser raro que el efecto dominó sea tan vasto (miles de líneas) que desee aplicar el cambio durante un período prolongado de tiempo.
    • Si este es el caso, implemente una herramienta de recopilación de métrica de código simple integrada en su proceso de compilación para informar el número de instancias pendientes.

Considero que el punto 2 es de importancia clave, sobre todo porque enfatiza la necesidad de cooperación y comunicación dentro del equipo.

Volviendo a mi declaración de apertura, cuanto antes detecte y repare un error, mejor.
¡Deje que el compilador informe un descanso! - Es la " primera oportunidad " mecanismo de informe de errores que tenemos.

¡Esos son mis 2 cobres! : D

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top