leer wikipedia con nuevo diseño

Programación reflectante


En ciencias de la computación , la programación reflexiva o la reflexión es la capacidad de un proceso para examinar, introspectar y modificar su propia estructura y comportamiento. [1]

Antecedentes históricos

Las primeras computadoras se programaron en sus lenguajes ensambladores nativos , que eran intrínsecamente reflectantes, ya que estas arquitecturas originales podían programarse definiendo instrucciones como datos y utilizando código auto modificable . A medida que la programación se trasladó a lenguajes compilados de nivel superior como Algol , Cobol y Fortran (pero también Pascal y C y muchos otros lenguajes), esta capacidad de reflexión desapareció en gran medida hasta que aparecieron los lenguajes de programación con reflexión incorporada en sus sistemas de tipos. [ cita requerida ]

La tesis doctoral de Brian Cantwell Smith de 1982 [2] [3] introdujo la noción de reflexión computacional en lenguajes de programación procedimental y la noción del intérprete meta-circular como un componente de 3-Lisp .

Usos

Reflection ayuda a los programadores a crear bibliotecas de software genéricas para mostrar datos, procesar diferentes formatos de datos, realizar la serialización o deserialización de datos para la comunicación, o agrupar y desagregar datos para contenedores o ráfagas de comunicación.

El uso efectivo de la reflexión casi siempre requiere un plan: un marco de diseño, descripción de codificación, biblioteca de objetos, un mapa de una base de datos o relaciones entre entidades.

La reflexión hace que un lenguaje sea más adecuado para el código orientado a la red. Por ejemplo, ayuda a lenguajes como Java a funcionar bien en redes al habilitar bibliotecas para serialización, agrupación y formatos de datos variables. Los lenguajes sin reflexión (por ejemplo, C ) tienen que utilizar compiladores auxiliares, por ejemplo, para la notación de sintaxis abstracta , para producir código para serialización y agrupación.

La reflexión se puede utilizar para observar y modificar la ejecución del programa en tiempo de ejecución. Un componente de programa orientado a la reflexión puede monitorear la ejecución de un recinto de código y puede modificarse a sí mismo de acuerdo con un objetivo deseado relacionado con ese recinto. Por lo general, esto se logra asignando dinámicamente el código del programa en tiempo de ejecución.

En lenguajes de programación orientados a objetos como Java , la reflexión permite la inspección de clases, interfaces, campos y métodos en tiempo de ejecución sin conocer los nombres de las interfaces, campos y métodos en tiempo de compilación. También permite la creación de instancias de nuevos objetos y la invocación de métodos.

La reflexión se utiliza a menudo como parte de las pruebas de software , como para la creación / creación de instancias de objetos simulados en tiempo de ejecución .

La reflexión también es una estrategia clave para la metaprogramación .

En algunos lenguajes de programación orientados a objetos, como C # y Java , la reflexión se puede utilizar para eludir las reglas de accesibilidad de los miembros . Para las propiedades de C #, esto se puede lograr escribiendo directamente en el campo de respaldo (generalmente invisible) de una propiedad no pública. También es posible encontrar métodos no públicos de clases y tipos e invocarlos manualmente. Esto funciona tanto para archivos internos del proyecto como para bibliotecas externas (.Net-assembly y Java-archive).

Implementación

Una reflexión de soporte de lenguaje proporciona una serie de funciones disponibles en tiempo de ejecución que, de otro modo, serían difíciles de lograr en un lenguaje de nivel inferior. Algunas de estas características son las capacidades para:

  • Descubra y modifique las construcciones de código fuente (como bloques de código, clases , métodos, protocolos, etc.) como objetos de primera clase en tiempo de ejecución.
  • Convierta una cadena que coincida con el nombre simbólico de una clase o función en una referencia o invocación de esa clase o función.
  • Evalúe una cadena como si fuera una declaración de código fuente en tiempo de ejecución.
  • Cree un nuevo intérprete para el código de bytes del lenguaje para darle un nuevo significado o propósito a una construcción de programación.

Estas funciones se pueden implementar de diferentes formas. En MOO , la reflexión forma parte natural del lenguaje de programación cotidiano. Cuando se llaman verbos (métodos), se completan varias variables como verbo (el nombre del verbo que se llama) y este (el objeto en el que se llama el verbo) para dar el contexto de la llamada. Por lo general, la seguridad se administra accediendo a la pila de llamadas mediante programación: dado que callers () es una lista de los métodos mediante los cuales se llamó finalmente al verbo actual, realizar pruebas en callers () [0] (el comando invocado por el usuario original) permite la verbo para protegerse contra el uso no autorizado.

Los lenguajes compilados se basan en su sistema de tiempo de ejecución para proporcionar información sobre el código fuente. Un ejecutable de Objective-C compilado , por ejemplo, registra los nombres de todos los métodos en un bloque del ejecutable, proporcionando una tabla para corresponderlos con los métodos subyacentes (o selectores de estos métodos) compilados en el programa. En un lenguaje compilado que admita la creación de funciones en tiempo de ejecución, como Common Lisp , el entorno de ejecución debe incluir un compilador o un intérprete.

La reflexión se puede implementar para lenguajes que no tienen funciones de reflexión incorporadas mediante el uso de un sistema de transformación de programas para definir cambios automatizados en el código fuente.

Ejemplos de

Los siguientes fragmentos de código crean una instancia foo de clase Foo e invocan su método PrintHello . Para cada lenguaje de programación , se muestran secuencias de llamadas normales y basadas en reflexión.

C#

El siguiente es un ejemplo en C # :

// Sin reflejo Foo  foo  =  new  Foo (); foo . PrintHello ();// Con objeto de  reflexión foo  =  Activador . CreateInstance ( "complete.classpath.and.Foo" ); MethodInfo  método  =  foo . GetType (). GetMethod ( "PrintHello" ); método . Invocar ( foo ,  nulo );

Delphi

Este ejemplo de Delphi asume que se ha declarado una clase TFoo en una unidad llamada Unit1 :

utiliza  RTTI ,  Unit1 ;procedimiento  WithoutReflection ; var  Foo :  TFoo ; comenzar  Foo  : =  TFoo . Crear ;  prueba  Foo . Hola ;  finalmente  Foo . Libre ;  terminar ; terminar ;procedimiento  WithReflection ; var  RttiContext :  TRttiContext ;  RttiType :  TRttiInstanceType ;  Foo :  TObject ; comience  RttiType  : =  RttiContext . FindType ( 'Unit1.TFoo' )  como  TRttiInstanceType ;  Foo  : =  RttiType . GetMethod ( 'Crear' ) . Invocar ( RttiType . MetaclassType ,  []) . AsObject ;  prueba  RttiType . GetMethod ( 'Hola' ) . Invocar ( Foo ,  []) ;  finalmente  Foo . Libre ;  terminar ; terminar ;

CE

El siguiente es un ejemplo en EC :

// Sin reflejo Foo  foo  {  }; foo . hola ();// Con clase de  reflexión fooClass  =  eSystem_FindClass ( __thisModule ,  "Foo" ); Instancia  foo  =  eInstance_New ( fooClass ); Método  m  =  eClass_FindMethod ( fooClass ,  "hola" ,  módulo fooClass . ); (( void ( * ) ()) ( void * ) m . función ) ( foo );  

Ir

El siguiente es un ejemplo en Go :

importar  "reflejar"// Sin reflejo f  : =  Foo {} f . Hola ()// Con reflexión fT  : =  reflexionar . TypeOf ( Foo {}) fV  : =  reflejar . Nuevo ( fT )m  : =  fV . MethodByName ( "Hola" ) si  m . IsValid ()  {  m . Llamar ( nulo ) }

Java

El siguiente es un ejemplo en Java :

import  java.lang.reflect.Method ;// Sin reflejo Foo  foo  =  new  Foo (); foo . hola ();// Con la reflexión intente  {  Object  foo  =  Foo . clase . newInstance (); Método  m  =  foo . getClass (). getDeclaredMethod ( "hola" ,  nueva  clase > [ 0 ] );  m . invocar ( foo ); }  catch  ( ReflectiveOperationException  ignorada )  {}

JavaScript

El siguiente es un ejemplo en JavaScript :

// Sin reflexión const  foo  =  new  Foo () foo . hola ()// Con reflexión const  foo  =  Reflect . construct ( Foo ) const  hola  =  Reflexionar . get ( foo ,  'hola' ) Reflexionar . aplicar ( hola ,  foo ,  [])// Con eval eval ( 'new Foo (). Hello ()' )

Julia

El siguiente es un ejemplo en Julia (lenguaje de programación) :

julia >  struct  Point  x :: Int  y  end# Inspección con la reflexión Julia >  Nombres de campo ( Point ) ( : x ,  : Y )julia >  fieldtypes ( Point ) ( Int64 ,  Cualquiera )julia >  p  =  Punto ( 3 , 4 )# Acceso con la reflexión Julia >  getField ( p ,  : x ) 3

C objetivo

El siguiente es un ejemplo en Objective-C , lo que implica que se utiliza el marco OpenStep o Foundation Kit :

// Clase Foo. @interface  Foo  : NSObject -  ( void ) hola ; @final// Envío de "hola" a una instancia de Foo sin reflexión. Foo  * obj  =  [[ Foo  alloc ]  init ]; [ obj  hola ];// Envío de "hola" a una instancia de Foo con reflejo. id  obj  =  [[ NSClassFromString ( @ "Foo" )  alloc ]  init ]; [ obj  performSelector :  @selector ( hola )];

Perl

El siguiente es un ejemplo en Perl :

# Sin reflexión my  $ foo  =  Foo -> new ; $ foo -> hola ;# o Foo -> nuevo -> hola ;# Con reflexión my  $ class  =  "Foo" my  $ constructor  =  "new" ; my  $ método  =  "hola" ;my  $ f  =  $ clase -> $ constructor ; $ f -> $ método ;# o $ clase -> $ constructor -> $ método ;# con eval eval  "nuevo Foo-> hola;" ;

PHP

El siguiente es un ejemplo en PHP :

// Sin reflejo $ foo  =  new  Foo (); $ foo -> hola ();// Con reflexión, usando Reflections API $ reflector  =  new  ReflectionClass ( 'Foo' ); $ foo  =  $ reflector -> newInstance (); $ hola  =  $ reflector -> getMethod ( 'hola' ); $ hola -> invocar ( $ foo );

Pitón

El siguiente es un ejemplo en Python :

# Sin reflexión obj  =  Foo () obj . hola ()# Con reflexión obj  =  globals () [ "Foo" ] () getattr ( obj ,  "hola" ) ()# Con eval eval ( "Foo (). Hola ()" )

R

El siguiente es un ejemplo en R :

# Sin reflexión, asumiendo que foo () devuelve un objeto de tipo S3 que tiene el método "hola" obj  <-  foo () hola ( obj )Con la reflexión # the.class  <-  "foo" the.method  <-  "hola" obj  <-  do.call ( the.class ,  la lista ()) do.call ( the.method ,  a-lista ( obj ))

Rubí

El siguiente es un ejemplo en Ruby :

# Sin reflejo obj  =  Foo . nuevo obj . Hola# Con reflexión class_name  =  "Foo" method_name  =  : hola obj  =  Objeto . const_get ( nombre_clase ) . nuevo obj . enviar  nombre_método# Con eval eval  "Foo.new.hello"

Xojo

El siguiente es un ejemplo usando Xojo :

'Sin reflejo Dim  fooInstance  como  nuevo  Foo fooInstance . ImprimirHola'Con reflexión Dim  classInfo  As  Introspection . Typeinfo  =  GetTypeInfo ( Foo ) Dim  constructores ()  Como  introspección . ConstructorInfo  =  classInfo . GetConstructors Dim  fooInstance  As  Foo  =  constructors ( 0 ). Invocar métodos Dim  () como introspección . MethodInfo = classInfo . GetMethods For Each m As Introspection . MethodInfo En métodos Si m . Name = "PrintHello" Entonces m . Invocar ( fooInstance ) End If Next                  

Ver también

  • Lista de plataformas y lenguajes de programación reflexivos
  • Espejo (programación)
  • Paradigmas de programación
  • Autohospedaje
  • Código auto modificable
  • Introspección de tipo
  • tipo de

Referencias

Citas

  1. ^ Un tutorial sobre la reflexión conductual y su implementación por Jacques Malenfant et al. (PDF) , desconocido, archivado desde el original (PDF) el 21 de agosto de 2017 , consultado el 23 de junio de 2019
  2. ^ Brian Cantwell Smith, Reflexión procedimental en lenguajes de programación , Departamento de Ingeniería Eléctrica y Ciencias de la Computación, Instituto de Tecnología de Massachusetts, Tesis doctoral, 1982.
  3. ^ Brian C. Smith. Reflexión y semántica en un lenguaje procedimental Archivado el 13 de diciembre de 2015 en la Wayback Machine . Informe técnico MIT-LCS-TR-272, Instituto de Tecnología de Massachusetts, Cambridge, Massachusetts, enero de 1982.

Fuentes

  • Jonathan M. Sobel y Daniel P. Friedman. Introducción a la programación orientada a la reflexión (1996), Universidad de Indiana .
  • Técnica Anti-Reflection usando C # y C ++ / CLI wrapper para prevenir el robo de código

Otras lecturas

  • Ira R. Forman y Nate Forman, Reflexión de Java en acción (2005), ISBN  1-932394-18-4
  • Ira R. Forman y Scott Danforth, Poniendo a trabajar las metaclases (1999), ISBN  0-201-43305-2

enlaces externos

  • Reflexión en programación lógica, funcional y orientada a objetos: un breve estudio comparativo
  • Introducción a la programación orientada a la reflexión
  • Páginas de Brian Foote sobre Reflexión en Smalltalk
  • Tutorial de la API de reflexión de Java de Oracle

This page is based on a Wikipedia article Text is available under the CC BY-SA 4.0 license; additional terms may apply. Images, videos and audio are available under their respective licenses.


  • Terms of Use
  • Privacy Policy