One of the key design points in AjTalk (Smalltalk-like VM written in C#) is to have easy access to underlying technology, in this case, .NET (I could reimplement the interpreter in Java). This is an easy to be able to use all the power of a class library and other libraries, written and tested in a wide ecosystem (data access, serialization, ORMs, GUIs, etc.). Then, I added some features in AjTalk to have such kind of access.
First, you can invoke .NET methods in .NET objects:
evaluates to “1”. It’s equivalent to this C# expression:
Note that you can write the method with an initial lower case letter. The number 1 is an integer, a System.Int32 in AjTalk, not an IObject (see … for a description of an IObject, the objects in AjTalk). You can invoke a method with parameters:
1 toString substring: 1 with: 2
Equivalent to C# expression:
You can use with: for the additional parameters. The method name is obtained from the first keyword in the message name, in the above example, substring:with: is the message symbol, and the native method is .Substring with two integers as parameters.
You can create new objects, accessing native types:
myFileInfo := @System.IO.FileInfo new: ‘FooBar.txt’
The @ precedes a .NET name, in this case, a type name. You can send messages new, new:, new:with:, etc, to invoke a constructor passing parameters. The above code it is equivalent to C# expression:
myFileInfo = new System.IO.FileInfo(“FooBar.txt”)
You can invoke static methods, too:
@System.IO.File exists: ‘FooBar.txt’
I added a twist, to the definition of classes:
Object subclass: #Collection
Collection subclass: #List nativeType: @System.Collections.ArrayList
myList := List new
myList add: 1
myList add: ‘foo’
The new thing is subclass:nativeType:. With the above code, you can use List, an AjTalk class, as a wrapper to native type System.Collections.ArrayList. The expression List new returns a native ArrayList, not an IObject wrapper. And you can use the native methods. In the example, I’m using add: as a way to call .Add native method on ArrayList object.
But you can add new AjTalk methods to that kind of classes:
Object subclass: #Rectangle nativeType: @AjTalk.Tests.NativeObjects.Rectangle
^self height * self width
rect := Rectangle new.
rect width: 10.
rect height: 20.
result := rect area
AjTalk.Tests.NativeObjects.Rectangle is a C# class with two properties Height and Width. The code adds a new method area. self points to the native object. Then, self height returns the .Height property of the native object.
If you want to call a native method explicit (just in case the method name were redefined), you can use ! (bang)
@System.IO.FileInfo !new: ‘NonexistentFile.txt’
Note that if you are using a fileIn-like format (AjTalk has a loader that reads a simplified format), you must repeat !:
@System.IO.FileInfo !!new: ‘NonexistentFile.txt’
Next topics for future posts: agents, distributed objects and transactional objects in AjTalk.