Hola. En esta secuencia vamos a ver la reflexión,
la capacidad de introspección en Pharo y por qué es útil.
Un sistema reflexivo,
la reflexión se divide en 2 familias principales,
Introspección
es la habilidad de un programa para observar su propio estado,
La intercesión es la habilidad de un programa. para modificarse.
Para modificar su propio estado o interpretación
La reificación es un concepto que consiste
de hacer cosas (objetos) explícitas que normalmente son implícitas.
Por ejemplo, la pila de ejecución
en Pharo es explícito, pero se puede obtener como un objeto clásico.
Más clásico, una clase en Pharo Es un objeto totalmente clásico.
En otros idiomas, Las clases no son objetos.
Un sistema reflexivo, como dije,
tiene su propia representación de sí mismo.
Es capaz de representarse a sí mismo,
y puede actuar en esta representación para modificarse,
y cuando se modifica a sí mismo cambia su estado y representación.
Lo llamamos una "conexión causal"
entre su representación y su estado
Si cambiamos el estado,
la representación del sistema cambia así como el estado del sistema.
¿Por qué es esto interesante? Es interesante porque usaremos
esta introspección e intercesión
para mirar dentro de los objetos
Estoy definiendo una colección, que hago una "Colección ordenada"
entonces usaré al Inspector Pharo, que es una herramienta,
que puede mirar dentro de este objeto.
Es un objeto de instancia de la clase OrderedCollection,
como vemos aquí, Tiene variables de instancia,
"primer índice", "último índice",
tenemos los valores de esto variables de instancia del objeto
entonces 1, 12 y luego una matriz de 12 elementos, ¿de acuerdo?
Podríamos preguntarnos cómo esta herramienta Inspector
Es capaz de mirar dentro de los objetos.
Como puede ver ¿El estado interno de los objetos?
Utiliza métodos de introspección para mirar dentro de los objetos,
Hay muchos de ellos, definido como "objetos".
Entonces "InstVarAt" nos permite ver
una instancia invariable de acuerdo a su número.
Veré la variable de instancia número 1 de este objeto.
Puedo modificar la variable de instancia número 1 de este objeto estableciendo un nuevo valor,
o puedo acceder a una instancia variable por su nombre,
o cambiarlo por su nombre, "InstVarNamed put". ¿OKAY?
Aquí hay unos ejemplos. Normalmente creamos un punto,
y luego hacemos ... el punto es 10 @ 3
instVarNamed:'x'.
Obtendré el valor de la instancia variable llamada 'x' de este punto,
que me da 10.
Entonces "instVarNamed:'x' puesto:33"
He cambiado el valor de la variable de instancia 'x' de este punto.
Se ha ido de 10 a 33.
He podido cambiar el estado interno de un objeto,
mediante el uso de la introspección y la intercesión,
particularmente intercesión, "InstVarNamed put". ¿OKAY?
El punto principal es que hemos violado la encapsulación.
Un objeto externo ha modificado Este objeto, sin ser interno,
por lo que viola la encapsulación pero es extremadamente útil
cuando se construyen herramientas y durante el desarrollo.
No debe usarse en la normalidad codigo de una aplicacion,
pero es extremadamente poderoso para construir herramientas genéricas,
típicamente inspectores de código.
Te daré otro ejemplo de introspección, el método de clase,
para obtener la clase de un objeto. Está definido en la clase "Objeto >>".
Le pido a esta cadena su clase, me da la cadena de clase,
este punto cuál es su clase, el punto de clase,
"Clase Smalltalk", Puedo preguntar a la clase de la clase.
etcétera, luego agrego clase de clase ...
Básicamente, puedo consultar el sistema
enviando el mensaje "clase" a objetos para descubrir su clase.
Hay muchos metodos para consultar el sistema.
Aquí, tomo "OrderedCollection" y envíe muchos mensajes de consulta.
Obtendré todas sus superclases,
todos sus selectores, el nombre de sus variables de instancia,
todos los selectores, el nombre de sus variables de instancia,
todas sus subclases, etc ...
Y todas sus líneas de código.
Todo esto nos permite construir herramientas de nivel superior,
como el sistema de navegación aquí.
Este sistema de navegación nos permite mostrar o explorar el sistema.
Por ejemplo, Puedo ver todas las clases
que implementa el método "#,".
Aquí tenemos una ventana que se abrirá.
Veremos todos los implementadores de #,
por lo que la clase "AbstractFileReference" implementa el método "#".
Tengo una lista de todas las clases. implementado por este método.
Otro ejemplo, nos gustaría implementar
un menú o un botón
Al hacer clic en él, queremos enviarlo un mensaje al objeto detrás de él,
de acuerdo con el nombre del botón, por ejemplo.
¿Cómo convierto una cadena en un mensaje? para enviar a un objeto?
Tengo un método de intercesión para eso. "Realizar" definido en "objeto".
Lo paso un símbolo, el nombre de un mensaje para ejecutar,
y enviará este mensaje al objeto en cuestión
Tengo un segundo tipo de mensaje, "actuar con".
Puedo dar el nombre del símbolo, el nombre del método para ejecutar,
y luego pasar una lista de argumentos.
Un ejemplo, si hago "5 factorial"
enviando un mensaje clásico, y enviar el mensaje reflexivo,
su "5 realiza # factorial" eso es un símbolo que significa,
"Objeto 5, por favor ejecuta o recibir el mensaje factorial ".
La búsqueda normal se aplica y estas dos formas son las mismas.
Aquí hay otro ejemplo.
Aquí tenemos un inspector de código
"Colección ordenada", podemos ver adentro la clase "Colección ordenada".
Esta clase contiene atributos,
variables de instancia, por ejemplo "methodDict".
En "methodDict" vemos que la clase "OrderedCollection"
viene de "Comportamiento" por lo que tiene un "métodoDicto" aquí,
una instancia de "MethodDictionary" que contiene "CompiledMethod".
Entonces podemos ver este diccionario de método contiene
un método compilado aquí, etc ...
otro método compilado ... Muchos de los métodos compilados.
Podremos preguntarles a cada uno de estos métodos compilados
por su código fuente. Si hago "self getSource"
Obtendré el código fuente del método compilado
Pero podemos ir más allá.
Se puede pedir un método compilado para ejecutarse directamente
con el mensaje, "valueWithReceiver:argumentos".
¡Pero cuidado! Si lo hago, no hay búsqueda.
Viendo como ya tengo un método compilado,
se ejecuta directamente sin un mensaje
Aquí preguntaré la clase entera para obtener su método compilado "factorial",
que obtengo de la método compilado de clase
Le envío el mensaje, "valueWithReceiver:argumentos".
Lo paso los argumentos, el receptor será 5,
los argumentos serán (), porque es un mensaje único,
y obtendremos el resultado.
Desencadena la ejecución de la Método compilado sin búsqueda.
Entonces, para resumir, La reflexión es extremadamente poderosa.
Hemos visto que es algo eso nos permite introspeccionar
todo el sistema porque lo representa
en sí mismo como un objeto,
sino también para modificar el estado del sistema
Nos permite construir herramientas de una manera genérica en todos los objetos.
Entonces realmente puedes hablar con objetos
con un protocolo estructuralmente Lo mismo para todos los objetos.
¡Pero cuidado! Viola la encapsulación.
No se usa en el código operativo, pero para la construcción de herramientas.
Facilita la escritura de inspectores de código como vimos,
y puedes ver cómo Está implementado en Pharo.