Riflessione (informatica)

Nella programmazione per computer , la riflessione è la capacità di un programma di esaminare, e possibilmente modificare, le proprie strutture interne di alto livello durante l' esecuzione .

Chiamiamo riflessività fa per un linguaggio di programmazione per consentire la scrittura di tali programmi. Si dice che un tale linguaggio di programmazione sia riflessivo .

Introspezione e intercessione

Ci sono due tecniche utilizzate dai sistemi riflettenti:

L' introspezione viene utilizzata per eseguire misurazioni delle prestazioni, ispezionare moduli o eseguire il debug di un programma. È implementato in linguaggi come Smalltalk o Java che forniscono strumenti per conoscere la classe di un oggetto, i suoi attributi , i suoi metodi , ecc. L'introspezione non esiste in linguaggi come C o Pascal (ma esiste in Delphi dalla versione 2010).

L' intercessione consente a un programma di cambiare automaticamente in base alle esigenze e all'ambiente. Questa proprietà appare in linguaggi come Smalltalk , Groovy o Python , ma non esiste in linguaggi come C.

La riflessione, l'introspezione e l'intercessione sono casi speciali di metaprogrammazione .

Pensiero strutturale e pensiero comportamentale

Accanto ai concetti di introspezione e intercessione, esistono due tipi di riflessione: riflessione strutturale (che riguarda principalmente il codice del programma) e riflessione comportamentale (che riguarda principalmente l'ambiente del programma).

La riflessione strutturale consiste nel reificare il codice di un programma e tutti i tipi astratti disponibili attraverso il programma. Nel primo caso, la reificazione del codice di un programma permette di gestire questo programma durante l'esecuzione. È così possibile mantenere un programma anche quando sta eseguendo delle attività. Nel secondo caso, la reificazione dei tipi astratti consente al programma di esaminare e modificare la struttura dei tipi complessi. È così possibile, ad esempio, sviluppare algoritmi di serializzazione generici .

La riflessione comportamentale (o comportamento di riflessione) si riferisce più in particolare all'implementazione del programma e all'ambiente del programma. Con questo tipo di riflessione un programma può "sapere" come viene interpretato e può quindi modificare il modo in cui viene eseguito, intervenendo sulle strutture dati del valutatore del programma e sul valutatore stesso. Il programma, infatti, può ottenere informazioni sulla sua attuazione o addirittura auto-riorganizzarsi per adattarsi al meglio a un “ambiente”.

Pensiero e programmazione a oggetti

Nella programmazione orientata agli oggetti , l'architettura riflessiva è implementata dal concetto di metaoggetti . Questi rappresentano elementi di programmi orientati agli oggetti come classi, messaggi e funzioni generiche. La manipolazione di questi metaoggetti avviene tramite un protocollo di metaoggetti che permette di decidere il comportamento del linguaggio. CLOS è il primo linguaggio ad aver implementato un protocollo meta-oggetto.

Linguaggi riflessivi

Le seguenti lingue sono riflessive:

Nei linguaggi interpretati o compilati al volo prima dell'esecuzione ( Lisp per esempio), non c'è differenza tra l'interpretazione del codice e la riflessione poiché è il codice sorgente che si evolve e non solo il codice risultante della compilazione.

Esempio

Il seguente esempio è scritto in Java  :

// Sans utiliser la réflexion Foo foo = new Foo(); foo.hello(); // En utilisant la réflexion Class<?> cl = Class.forName("package.name.Foo"); // Instanciation de l'objet dont la méthode est à appeler Object instance = cl.newInstance(); // Invocation de la méthode via réflexion Method method = cl.getClass().getDeclaredMethod("hello", new Class<?>[0]); method.invoke(instance);

L'esempio seguente è scritto in C#  :

// Sans utiliser la réflexion Foo foo = new Foo(); foo.hello(); // En utilisant la réflexion Type type = typeof(Foo); // Instanciation de l'objet dont la méthode est à appeler // Il existe deux façons d'instancier un objet via la réflexion : // 1, soit : ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes); object instance = constructor.Invoke(new object[]{}); // 2, soit : instance = Activator.CreateInstance(type); // Invocation de la méthode via réflexion MethodInfo method = type.GetMethod("hello"); method.Invoke(instance, new object[]{});

I due pezzi di codice creano un'istanza della classe Foo e chiamano il loro metodo hello .

Nel primo programma, i nomi delle classi e dei metodi sono codificati, non è possibile utilizzare il nome di un'altra classe. Nel secondo programma, invece, i nomi delle classi e dei metodi possono variare in fase di esecuzione.

Bibliografia

  • DG Bobrow, RG Gabriel e JL White. Programmazione orientata agli oggetti: la prospettiva CLOS . MIT Press, 1993.
  • G. Kickzales, J. des Rivières e DG Bobrow. L'arte del protocollo metaoggetto . MIT Press, 1991.

Vedi anche