Comentario intrascendente…

junio 11, 2008 en Artículos, Delphi, Entrada Diario

Siento la ausencia de estos días pero voy un poco sobrecargado de trabajo. :-( Y francamente, al llegar a casa, apenas me queda tiempo para escribir una sola linea. De hecho, tengo a medias la próxima entrada del Blog que continuaba profundizando en los cambios introducidos en Delphi 2007 y que no suelen ser demasiado conocidos.

El tema giraba sobre la sobrecarga de operadores, que ya es posible (y aquí viene la parte mas estrambótica) a nivel de la estructura de Registro. Se le pone a uno lo pelos como escarpias, cuando ve que es posible aplicar la sobrecarga en Delphi .Net a nivel de clases y que aquí nos hemos quedado como el tío faba (es una expresión de mi tierra) aplicando estas novedades a una estructura que en mi opinión tenía un menor peso especifico.

En fin… Desde Delphi 2 llevo oyendo a unos y a otros la importacia de las clases en la programación orientada a objetos, llenándose la boca de grandes discursos, para ver como ahora mismo, se le dota a la estructura de los registros, de unas funcionalidades que le acercan mas a las clases, sin que yo encuentre demasiado sentido a este giro… :-) Yo creo que hubiera sido mas oportuno haber dotado a una estructura como la clase de la sobrecarga de operadores pero posiblemente existan razones técnicas que queden mas allá de nuestro entendimiento para comprender el porque de una decisión como esta. Si hay alguien que lo entienda por favor que me lo explique.

Como dijo alguien en alguna ocasión, que cada mástil aguante su vela…

Algunas ventajas… (¡si eres capaz de recordarlas!) – Parte II

mayo 1, 2008 en Artículos, ¿Sabías que...?, ¿Sabías que...? [Delphi], Consejo, Delphi, Enlace interesante, Entrada Diario

Seguimos nuestro camino, persiguiendo la estela de cambios que nos proponía el enlace de la entrada anterior, pero sin abandonar la perspectiva que nos acompañaba en la parte I.

Hablabamos de ámbito y lo hacíamos fijandonos desde nuestro módulo de código hacia el exterior. Pero… es interesante fijar nuestra vista hacia el interior del mismo para descubrir que por fin, tras muchos años de subsistencia de un ambito de visibilidad que no nos permitía ocultar las declaraciones privadas de cada clase dentro del mismo módulo de datos, nos ha llegado un especificador de ambito que subsana el “problema”… Esto no es propio de 2007 pues ya es incorporado en las versiones anteriores pero quizás porque ambas han pasado con mas penas que gloria, es por lo que muchos puedan apercibirse de ello con los primeros pasos en el entorno de Delphi 2007. Creo recordar que en terminos coloquiales se hablaba de clases “amigas”. Ahora amistad es una cosa y confianza otra… :-) ¡Gracias a Dios!

El especificador de ambito restrictivo (strict) modifica tanto a private como a protected para que realmente la declaraciones hechas en los respectivos ambitos se oculten. En el caso de strict protected, se entiende perfectamente que solo va a poder ser visible las declaraciones de ese ámbito en una clase descendiente. Sin embargo, parece acertado que se haya mantenido la compatibilidad hacia atras permitiendo que private y protected sigan manteniendo el mismo comportamiento, lo cual hasta cierto punto es bastante razonable… ¡lo contrario hubiera sido un disparate! :-)

Pero lo mejor es poder verlo con un par de lineas de codigo que no van a compilar, precisamente porque vamos a violar expresamente un campo calificado como strict private desde el formulario.

unit uMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  THolaMundo1 = class
  private
    fSaludo: String;
  public
    procedure Saludar;
  end;

  THolaMundo2 = class
  strict private
    fSaludo: String;
  public
    procedure Saludar;
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  f: THolaMundo1;
begin
   f:= THolaMundo1.Create;
   try
      f.fSaludo:= 'Hola Mundo';  //[private] podemos acceder
      f.Saludar;
   finally
        f.Free;
   end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  f: THolaMundo2;
begin
   f:= THolaMundo2.Create;
   try
      f.fSaludo:= 'Hola Mundo';  //[strict private] no podemos acceder a fSaludo
      f.Saludar;
   finally
        f.Free;
   end;
end;

{ THolaMundo2 }

procedure THolaMundo2.Saludar;
begin
   ShowMessage(fSaludo);
end;

{ THolaMundo1 }

procedure THolaMundo1.Saludar;
begin
   ShowMessage(fSaludo);
end;

end.

El error que nos genera es: “Cannot access private symbol “THolaMundo2.Saludo”.

De todas formas, cualquier programador, con independencia de haber aplicado la restricción de ambito, hubiera seguido las directrices de ocultación que nos marca la lógica de la programacion orientada a objetos y no violaría el acceso a los campos desde métodos o asignaciones directas que no fueran establecidas desde la parte publicada de la clase, que es para nosotros un contrato a cumplir. Eso nos dice la lógica…Luego cada uno, haga de su capa un sayo…
:-)

Algunas ventajas… (¡si eres capaz de recordarlas!) – Parte I

abril 27, 2008 en Advertencia, Artículos, ¿Sabías que...?, ¿Sabías que...? [Delphi], Consejo, Delphi, Enlace interesante, Entrada Diario

Hoy he encontrado un pequeño recurso en castellano, en las páginas de Codegear, y me ha parecido muy interesante. Se corresponde a una de las entradas existentes en su web, escritas por Andreano Lanuse y que habla de las ventajas de migrar desde delphi 7 a Delphi 2006. Andaba hace tiempo buscando un documento similar, que me sirviera de guión para ir compartiendo con vosotros su contenido. Y como siempre que encuentro algo interesante, quería compartirlo con vosotros:

http://dn.codegear.com/print/33963

Aunque el título hace referencia a Delphi 2006, se entiende que lo extendemos a Delphi 2007 para Win32. Y justamente buscaba algo así: un escrito no demasiado extenso, que pudiera reunir las últimas novedades que introduce el lenguaje, porque me había hecho el ánimo de hacer alguna entrada abordando dicho tema. No solo ya para ampliar el contenido del blog, sino para mi mismo, para tomar conciencia de que están y de que puedo llegar a usarlas. Eso sí. Debeis de tener en cuenta de que hay algunos cambios introducidos propios de Delphi 2007 que no se mencionan en dicho documento y que afectan a areas como la compatibilidad con Windosws Vista (¡recordad por poner un ejemplo, la disponibilidad de componentes diálogos propios de éste).

Y el caso, es que una gran parte de estas mejoras y cambios pueden pasarte inadvertidas fácilmente si no se hace uno el ánimo de ir incorporandolas a los recursos que uno habitualmente utiliza.

Me viene a la mente el caso de las clases anidadas…

Ya habeis podido leer en el artículo de Andreano Lanusse, que es uno de los cambios que nos van a permitir definir una subclase dentro de otra, quedando como el mismo nombre nos indica -anidada-. El tema se extiende tambien a las constantes, que van a poder anidarse dentro de la clase contenedora; lo que ellos llaman Nested Constants (Constantes anidadas)

Y la pregunta que se puede hacer un programador que lleve poco tiempo desarrollando con Delphi, es comprender que aporta esta novedad con respecto a las versiones anteriores… Tendríamos que hablar de ámbito y de visibilidad de las clases. Es decir, una clase anidada es accesible tan solo a través de la clase que la contiene, lo cual, permite cumplir compromisos de ocultación o encapsulación que no podían ser cumplidos desde las versiones anteriores, como Delphi 7. Si en una clase ibamos a necesitar los ambitos: private, protected, etc… a nivel de campos, por poner un ejemplo. Nos hacia falta otro recurso que nos permitiera extender este concepto a nivel de interfaz públlico. Dos clases definidas en el mismo módulo, en la sección de interfaz (interface) siempre se nos presentaban con un ambito global, desde fuera del módulo y eran accesibles por cualquier otra clase desde otro módulo distinto. Para ocultar una clase, nos obligabamos a definirla en la sección de implementación, que restringía el acceso a la misma desde clases ubicadas en otros módulos.

Vamos a imaginarnos un pequeño ejemplo mas rebuscado, que nos ponga en una tesitura similar…

Supogamos que tenemos un formulario de inicio de sesión, en el que pusimos un par de componentes que nos permitan editar el nombre de usuario y la contraseña y dos botones: uno para cancelar y otro para aceptar. Nuestro programador, por la razón que sea (¡quien conoce al alma humana!) se empeña en que sirva de base para otros formularios que redefinan su comportamiento. Es decir, que nuestro formulario que vemos en la imagen que figura mas abajo, no hace nada. Nada en absoluto. Lo haran sus descendientes… :-)

unit uFormulario;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics,
  Controls, Forms, Dialogs, StdCtrls, Buttons, Mask;

type
  TFormulario = class(TForm)
    labUsuario: TLabel;
    labPassword: TLabel;
    ediUsuario: TEdit;
    mskPassword: TMaskEdit;
    btnOk: TBitBtn;
    btnCancel: TBitBtn;
  private
    { Private declarations }
  protected
    function MostrarFormulario: TModalResult; virtual; abstract;
  public
    { Public declarations }
end;

var
  Formulario: TFormulario;

implementation

{$R *.dfm}

{ TFormulario }

end.

Pues bien… Veamos como podríamos plantearnos el tema desde la perspectiva de Delphi 7, si pretendieramos hacer uso de la herencia para redefinir su comportamiento en nuestra aplicacion. Podríamos optar a una solución como la que sigue.

unit umain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, uFormulario;

const MiSaludo = 'Bienvenido...';

type
  TInicioSesion = class(TFormulario)
   public
    function MostrarFormulario: TModalResult; override;
  end;

  TForm1 = class(TForm)
  private
    { Private declarations }
   MiFormulario: TInicioSesion;
   public
    { Public declarations }
   constructor Create(AOwner: TComponent); override;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TForm1 }

constructor TForm1.Create(AOwner: TComponent);
begin
  inherited;
  MiFormulario:= TInicioSesion.Create(Application);
  if MiFormulario.MostrarFormulario <> mrOk then
    Application.Terminate;
end;

function TInicioSesion.MostrarFormulario: TModalResult;
begin
  Caption:= MiSaludo;
  Result:= ShowModal;
end;

end.

Sin embargo, la solución propuesta contiene un problema moral, que es la visibilidad de la clase TInicioSesion desde modulos externos de la misma aplicación. ¡Vamos! ¡Qué no es un problema técnico! Cuando digo moral me refiero exactamente a eso. Es como cuando programo en la empresa con mi compañero de trabajo, y hacemos uso del controlador de versiones Jedi VCS, cuando realmente lo tengo frente a mi mesa y podría saber en cualquier momento que módulos tiene abiertos, sin tener que consultar el interfaz de proyectos de Jedi. Aquí pasa algo parecido, puesto que soy yo el que decido en cualquier momento quien va a acceder a cada módulo, con independencia de su visibilidad.

Sin embargo, Delphi 2007 nos permite otra perspectiva que de forma natural resuelve nuestro problema moral. Veamos el planteamiento…

unit umain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, uFormulario;

type
  TForm1 = class(TForm)
  private
    { Private declarations }
    MiFormulario: TFormulario;
    const MiSaludo = 'Bienvenido...';
    type
      TInicioSesion = class(TFormulario)
      public
        function MostrarFormulario: TModalResult; override;
      end;
   public
    { Public declarations }
   constructor Create(AOwner: TComponent); override;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TForm1 }

constructor TForm1.Create(AOwner: TComponent);
begin
  inherited;
  MiFormulario:= TInicioSesion.Create(Application);
  if (MiFormulario as TInicioSesion).MostrarFormulario <> mrOk then
    Application.Terminate;
end;

{ TInicioSesion }

function TForm1.TInicioSesion.MostrarFormulario: TModalResult;
begin
  Caption:= MiSaludo;
  Result:= ShowModal;
end;

end.

Ambos códigos hacen exactamente lo mismo. La diferencia es el matiz de la visibilidad de la clase TInicioSesion, que cumple con mayor naturalidad los requisitos que nos demanda la programación orientada a objetos. Os dejo que lo reflexioneis y seguiremos hablando en esta y sucesivas entradas.

Ahh… un detalle mas para los que realmente se inician en Delphi… Hemos puesto:

MiFormulario:= TInicioSesion.Create(Application);

¿Piensas que hubiera funcionado “Application.CreateForm(TInicioSesion, MiFormulario);”?

¡Claro que no!… pero también es una buena reflexión pensar el por qué no. ;-)

Jugar al escondite…

febrero 3, 2008 en Artículos, Delphi, Entrada Diario

Llevo un rato pensando en como traducir las palabras “CODE FOLDING” para poder escribir esta pequeña entrada. No se si la traducción correcta es “código encarpetado”. Y la verdad es que, aunque no suena demasiado bien, el concepto ya se intuye y promete ser util, como todo lo que intento compartir con vosotros.

Pero a lo que vamos…

¿Qué es eso de Code Folding…?

Pues vereis, desde Delphi 2005, se introduce una nueva característica en el editor de Delphi, que nos va a permitir esconder o visualizar en bloques definidos nuestro codigo, facilitando el trabajo en cada uno de los modulos que generamos. Cada módulo presenta menos lineas a nuestra vista y podremos trabajar mas cómodamente.

El entorno ya facilita parte del trabajo agrupando de forma automatica distintas zonas del módulo, inclusive cada uno de los procedimientos y funciones de la implementación, pero -y esto es quizás la parte mas práctica- vamos a poder crear nuestros propios apartados, que son llamados REGIONES. La idea es práctica y es muy fácil de poner a la práctica.

Venga… no seais perezosos. :-)

Abrid vuestro editor de Delphi 2007 y vamos a verlo.

Para activar o desactivar esta característica, debéis pulsar las teclas [CONTOL] +[SHIFT]+ K + O respectivamente.

Esta es la imagen que nos muestra el editor si está desactivada. Podeis ver que no muestra los símbolos +/-

Si volveis a pulsar la misma combinación de teclas, apareceran expandidos los distintos nodos, mostrando el siguiente aspecto. Ahora ya muestra los símbolos +/- en la raiz de cada nodo creado.

Así que, ya podeis apreciar que al colapsar algunos de los nodos, tal y como hemos hecho en la imagen que ahora veis un poco mas abajo, lo que logramos es ocultar de nuestra vista detalles innecesarios, facilitando enormemente nuestro trabajo.

Finalmente, y esta es la parte que mas me gusta, al poder crear una región, vamos a tener la capacidad de organizar visualmente nuestro código de acuerdo al mejor criterio.

Crear una REGION es sencillo. Inserta la directiva {$REGION ‘Nombre de la region’} , encabezando las lineas que deseas agrupar. Y cierras la última linea añadiendo {$ENDREGION}. Así de facil.

{$REGION 'EVENTO CREACION FORMULARIO'}
procedure TForm1.FormCreate(Sender: TObject);
begin
//mensaje de bienvenida
ShowMessage('Hola Mundo');
end;
{$ENDREGION}

Así que al colapsar los nodos asociados a las regiones, podemos tener una vista de nuestro módulo donde se agrupen visualmente los distintos procedimientos y funciones, facilitando la lectura del código y nuestra navegación a traves del mismo.

Estas son las combinaciones de teclas disponibles:

  • [Control] + [Shift]+ K + O -> Activa o desactiva la característica Code-Folding.
  • [Control] + [Shift]+ K + A -> Expande todos los bloques de código
  • [Control] + [Shift]+ K + E -> Colapsa el siguiente bloque.
  • [Control] + [Shift]+ K + U -> Expande el siguiente bloque.

Presentacion de Delphi 2007

abril 20, 2007 en Entrada Diario

El viernes 13 de Abril se celebró en Madrid, en el Hotal Puerta de América, el Acto de presentación de Delphi 2007 para Win32 y Delphi para PHP. Tuve la oportunidad de acudir a este evento y no quise desaprovecharla. En fin… fueron 400 kms y lo que escuché y vi, me pareció bastante positivo.

Tampoco soy demasiado experto en este tipo de eventos. Y mi opinión es la de un sencillo programador de provincias, casi diría de pueblo, ya que la boina no nos la sacamos cuando nos desplazamos a la ciudad…

:-)

He remitido a Jose Luis Freire un pequeño resumen de lo que se comentó en la presentación y si no me equivoco, en los proximos días os lo enviará en forma de Boletín extraordinario.

Y no quisiera crear expectativas que luego no respondan a la realidad… pero creo que la llegada de esta nueva empresa traerá nuevos aires a nuestras herramientas de desarrollo. Renovarse o morir… ;-)