Uno de los puntos de diseño principales en AjTalk (mi proyecto de código abierto implementando una Virtual Machine tipo Smalltalk en C#) es tener accceso a la tecnología de implementación, en este caso, .NET (podría reescribir el proyecto en Java). Con esta facilidad podemos acceder a todo el poder de una librería de clases, y a otras librerías, escritas y ya probadas en un amplio ecosistema (.NET en este caso), como librerías de acceso a datos, serialización, GUIs, ORMs, etc. Para cumplir con este punto de diseño agregué algunas características a AjTalk para tener ese tipo de acceso.
Primero, podemos invocar métodos .NET en objetos .NET:
1 toString
retorna “1”. Es equivalente a la expresión C#:
1.ToString()
Notemos que podemos escribir el método con una letra inicial en minúscula (no es obligatorio). El número 1 es un entero, un System.Int32 en AjTalk, no un IObject (ver Trabajando en AjTalk: una Virtual Machine tipo Smalltalk en C# para una descripción de un IObject, que son los objetos de AjTalk). Podemos invocar un método con parámetros:
1 toString substring: 1 with: 2
Equivalente a la expresión C#:
1.ToString().Substring(1,2)
Podemos usar with: para los parámetros adicionales. El nombre de método es obtenido de la primera palabra del nombre del mensaje, en el caso de arriba, substring:with: es el símbolo del mensaje, y el método nativo es .Substring con dos enteros como parámetros.
Podemos crear nuevos objetos .NET, accediendo a los tipos nativos:
myFileInfo := @System.IO.FileInfo new: ‘FooBar.txt’
El @ precede al nombre .NET, en este caso, un nombre de tipo. Podemos enviar los mensajes new, new:, new:with:, etc, para invocar un constructor pasando parámetros. El código de arriba es equivalente a:
myFileInfo = new System.IO.FileInfo(“FooBar.txt”);
Podemos invocar métodos estáticos, también:
@System.IO.File exists: ‘FooBar.txt’
Agregué un “truco”, me parece interesante, a la definición de las clases:
Object subclass: #Collection
!
Collection subclass: #List nativeType: @System.Collections.ArrayList
!
myList := List new
!
myList add: 1
!
myList add: ‘foo’
!
Lo nuevo es el nombre de mensaje subclass:nativeType:. En el código de arriba, podemos usar List, una clase AjTalk, como un “wrapper” a un tipo nativo System.Collections.ArrayList. La expresión List new retorna un ArrayList nativo, no un “wrapper” basado en IObject. Y podemos usar los métodos nativos. En este ejemplo, podemos llamar al método nativo .Add en el objeto ArrayList.
Pero hasta podemos agregar nuevos métodos AjTalk a esas clases sobre tipos nativos:
Object subclass: #Rectangle nativeType: @AjTalk.Tests.NativeObjects.Rectangle
!Rectangle methods!
area
^self height * self width
! !
rect := Rectangle new.
rect width: 10.
rect height: 20.
result := rect area
!
AjTalk.Tests.NativeObjects.Rectangle es una clase C# que escribí para prueba, con dos propiedades Height y Width. El código agrega un nuevo método area. self apunta a un objeto nativo. Entonces, self height retorna la propiedad .Height del objeto .NET.
Podemos llamar a un método nativo explícitamente (por si el nombre del método fue redefinido), podemos usar ! (signo de admiración)
FileInfo
:=
@System.IO.FileInfo !new: ‘NonexistentFile.txt’
Notemos que si usamos un formato tipo fileIn de Smalltalk (AjTalk tiene un lector de ese formato, simplificado), tenemos que repetir el ! (uno solo indica el fin de un chunck, a ejecutar en general en el momento).
FileInfo
:=
@System.IO.FileInfo !!new: ‘NonexistentFile.txt’
!
Próximos temas a tratar en posts: agentes, objetos distribuidos, y objetos transaccionales en AjTalk.
Nos leemos!
Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez