Todavía me estoy haciendo a la idea de que existen esos nuevos artilugios infernales llamados genéricos y anónimos y ayer, por vez primera creo que busqué profundizar con más detalle en estós últimos. Reconozco que mi capacidad para imaginar qué pueden hacer y qué pueden aportarme anda bajo mínimos (siempre estuvo así, pero ahora quizás con más razón) y me resulta chocante descubrir nuevas lineas de código, que intento descifrar con la misma naturalidad que sentimos al fijar la vista sobre aquello que se nos muestra turbio.

Así que uno va leyendo y acumulando ideas con la esperanza de que en algun momento se aclare esa visión y vea nítidamente la panorámica y el escenario.

En esas pesquisas, descubría un enlace que me pareció muy interesante y que hablaba de los métodos anónimos, y lo que es mejor, razonaba sobre su comportamiento y sobre como, desde ellos, se accede a las variables que caen fuera de propio ambito. En este caso concreto, el metodo accede a una variable local al procedimiento que lo invoca. El experimento resulta muy curioso.

Está era la conclusión:

Aha!  So it’s not stored on the stack after all; it’s treated more or less as a var parameter referring to a field inside the closure object.  It’s referenced as [esi + $0C], so our “local” variable is stored 12 bytes in, which is right where we’d expect to find the first data field on an object that implements two interfaces: IInterface and the “anonymous method interface” for this closure.  This explains why an anonymous method can’t capture by-reference parameters

Os aconsejo su lectura (aunque está en ingles), pero creo que se puede entender ( y desde luego si yo lo entiendo vosotros casi con seguridad también, porque mi inglés todavía anda verde como el brote del olivo)

TURBU Tech

Al mismo tiempo que leía los fragmentos de código, algunas neuronas elucubraban hipótesis que me sugería la misma contemplación de aquellas lineas escritas. Y es que me preguntaba si era posible que un método anónimo invocara otro anidado, lo cual me sorprendía a mi mismo que tuviera utilidad alguna. Pero que lechess!!!  Nadie puede estar preguntandose algo y esperar que le respondan, así que modifiqué con un par de lineas para adaptarlo a  mi nueva duda existencial…

 

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Dialogs;

type
   TAnonProc = reference to procedure;

procedure doStuff;
var
   counter: integer;
   i: integer;
   countProc: TAnonProc;
begin
   counter := 4;
   countProc := procedure
                begin
                   countProc:= procedure
                    begin
                      countProc:= procedure
                      begin
                         inc(counter);
                      end;
                   end;
                end;
   for i := 1 to 10 do countProc;
   writeln(counter);
end;

begin
   try
      doStuff;
   except
   on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
   end;
   readln;
end.

Esta es la imagen que mostraba la ventana tras ejecutar el código. Logico ¿no? El valor del contador se inicia en cuatro y en el bucle se itera el codigo diez veces, de las cuales dos solo asignan el valor de la referencia al método.

¡Y yo que pensaba que iba a dar un error o algo similar!

🙂
anonimos

Cuando era niño, y de eso ya hace algunos años, comercializaban unas bolsas de patatas fritas en las que se podía ver un niño, que sujetaba con alegria la bolsa. Si uno se fijaba con detalle, en la bolsa que el niño sujetaba, se podía ver la imagen del mismo niño sujetando las patatas, y así hasta donde se perdía nuestra imaginación y nuestra curiosidad…

🙂

Un comentario sobre “Esos dichosos métodos anónimos

  1. en el bucle se itera el codigo diez veces, de las cuales dos solo asignan el valor de la referencia al método
    Me tomó un minuto comprenderlo. Muy cierto Salvador, las dos primeras pasadas del ciclo solamente asignan un procedimiento a la variable CountProc. Es a partir de la pasada #3 cuando se ejecuta al procedimiento Inc. 🙂

    Muy interesante.

    Al González. 🙂

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s